【省选模拟】20/06/05

2024-01-30 00:58
文章标签 模拟 05 20 06 省选

本文主要是介绍【省选模拟】20/06/05,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

A A A

  • l d x ldx ldx 大神的 60 60 60 分做法:
    用二元组 ( a , b ) (a,b) (a,b) 记录最小段数和最小代价来 d p dp dp,记 d p i dp_i dpi 表示以 i i i 结尾的最小值
    考虑如何为一个区间选择一个最优的匹配点,暴力枚举 d p j dp_j dpj,考虑将某一个区间从 j j j 挪到 i i i,这对应一个关于 i , j i,j i,j 的二元一次函数,用三元组 ( a , b , c ) (a,b,c) (a,b,c) 可以表示出这个系数
    系数预处理是个二维平面修改,差分后求矩阵的前缀和,可以做到 O ( n 2 ) O(n^2) O(n2)

  • 这个 d p dp dp 看起来不能优化了,考虑一些性质,设贪心出来选出来的点为 p 1 , p 2 , … , p k p_1,p_2,\dots,p_k p1,p2,,pk,那么 ( p 0 , p 1 ] , ( p 1 , p 2 ] , … , ( p k − 1 , p k ] (p_0,p_1],(p_1,p_2],\dots,(p_{k-1},p_k] (p0,p1],(p1,p2],,(pk1,pk] 的每个区间必然存在且仅存在一个点,显然大于一个点是不可能的,若存在一个区间没有点,那么必定存在一个区间满足 l i ∈ ( p t − 1 , p t ] , r i = p t l_i\in (p_{t-1},p_t],r_i=p_t li(pt1,pt],ri=pt,不合法

  • 同时注意到,一个区间的中点必定可以定位到两个点之间,且最优值只会取到两个端点的一个
    前缀和简单询问每个区间的系数 c o e f l , r coef_{l,r} coefl,r,于是可以暴力 d p dp dp
    d p i = min ⁡ d p j + c o e f j , i ( j ∈ ( p t − 1 , p t ] ) dp_{i}=\min dp_j+coef_{j,i}(j\in(p_{t-1},p_t]) dpi=mindpj+coefj,i(j(pt1,pt]),又注意到对于 c o e f i , r , c o e f j , r ( i < j ) coef_{i,r},coef_{j,r}(i<j) coefi,r,coefj,r(i<j) i i i 的增量始终大于 j j j 的增量,可以分治解决

#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define fi first
#define se second
using namespace std;
namespace IO{cs int Rlen=1<<22|1;inline char gc(){static char buf[Rlen],*p1,*p2;(p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin));return p1==p2?EOF:*p1++;} int read(){int x=0; char c=gc(); bool f=false;while(!isdigit(c)) f=c=='-', c=gc();while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48), c=gc();return f?-x:x;}
} using namespace IO;
typedef long long ll;
cs ll INF = 1e18;
void ckmin(int &a, int b){ if(a > b) a = b; }
void ckmax(int &a, int b){ if(a < b) a = b; }
cs int N = 2e6 + 50;
struct my{ int l, r; };
bool cmp(cs my &a, cs my &b){ return a.l < b.l || (a.l == b.l && a.r > b.r); }
int n, m, Ans; my a[N], b[N];
int rp[N], A; ll Sm[N]; int ct[N];
ll dp[N]; int lm[N], mx[N];
ll calc(int l, int r){if(l==0) return (ll)r*ct[r]-Sm[r];if(r>A) return Sm[r]-Sm[l]-(ll)l*(ct[r]-ct[l]);int mid = (l+r)>>1; assert(l<=r);ll lv = Sm[mid]-Sm[l]-(ll)l*(ct[mid]-ct[l]);ll rv = (ll)r*(ct[r]-ct[mid])-(Sm[r]-Sm[mid]);return lv + rv;
}
void work(int L, int R, int l, int r){if(L>R) return; int mid = (L+R) >> 1;int trs = 0; ll mn = INF;for(int i = max(lm[mid],l); i <= r; i++){ll t = dp[i] + calc(i,mid);if(t < mn) mn = t, trs = i;} dp[mid] = mn;work(L,mid-1,l,trs); work(mid+1,R,trs,r);
}
int main(){#ifdef FSYolandafreopen("1.in","r",stdin);#endifscanf("%d",&n);for(int i=1; i<=n; i++)a[i].l=read()<<1, a[i].r=read()<<1, A=max(A,a[i].r);sort(a+1,a+n+1,cmp);for(int i=1; i<=n; i++){while(m && a[i].r <= b[m].r) --m;b[++m] = a[i];} for(int l=1,r=1;l<=m;l=r){while(r<=m&&b[r].l<=b[l].r) ++r;++Ans; rp[Ans] = b[l].r;} rp[Ans+1] = A+1; for(int i=1,x; i<=n; i++){x=(a[i].l+a[i].r)>>1;++ct[x]; Sm[x]+=x;} for(int i=1; i<=A+1; i++) Sm[i]+=Sm[i-1],ct[i]+=ct[i-1];for(int i=1; i<=rp[1]; i++) dp[i] = calc(0,i);for(int i=1; i<=n; i++) mx[a[i].r]=max(mx[a[i].r],a[i].l);for(int i=1,lp=0; i<=A+1; i++) lm[i]=lp, lp=max(lp,mx[i]);for(int i=1; i<=Ans; i++) work(rp[i]+1,rp[i+1],rp[i-1]+1,rp[i]);cout << Ans << " " << dp[A+1];return 0;
}

B B B

  • 点分树即可,用 z k w zkw zkw 线段树维护一下子树的某个区间的最近距离, O ( n log ⁡ 2 n ) O(n\log^2 n) O(nlog2n),可以跑过 O ( n log ⁡ n ) O(n\log n) O(nlogn) 的线段树分治 + 虚树
#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define fi first
#define se second
using namespace std;
namespace IO{cs int Rlen=1<<22|1;inline char gc(){static char buf[Rlen],*p1,*p2;(p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin));return p1==p2?EOF:*p1++;} int read(){int x=0; char c=gc(); bool f=false;while(!isdigit(c)) f=c=='-', c=gc();while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48), c=gc();return f?-x:x;}
} using namespace IO;
cs int N = 1e5 + 50;
cs int INF = 1e9 + 7;
int n, m, fi[N], nxt[N<<1], to[N<<1], w[N<<1], ec;
void adde(int u, int v, int c){ nxt[++ec]=fi[u]; fi[u]=ec; to[ec]=v; w[ec]=c; 
}
int d[18][N], fa[N], dep[N];
int sz[N], mx, rt; bool ban[N];
void gsz(int u, int fa){sz[u]=1;for(int e=fi[u],v;e;e=nxt[e])if(!ban[v=to[e]]&&to[e]!=fa)gsz(v,u),sz[u]+=sz[v];
}
void grt(int u, int fa){int now=sz[0]-sz[u];for(int e=fi[u],v;e;e=nxt[e])if(!ban[v=to[e]]&&to[e]!=fa)grt(v,u),now=max(now,sz[v]);if(now<mx) mx=now,rt=u;
}
void dfs(int dt, int u, int fa){for(int e=fi[u],v;e;e=nxt[e])if(!ban[v=to[e]]&&to[e]!=fa)d[dt][v]=d[dt][u]+w[e],dfs(dt,v,u);
}
vector<int> G[N];
void work(int u, int an, int d){gsz(u,0); sz[0]=mx=sz[u]; rt=0; grt(u,0);ban[u=rt]=true; fa[u]=an; dep[u]=d; dfs(d,u,0); if(an) G[an].pb(u);for(int e=fi[u];e;e=nxt[e])if(!ban[to[e]]) work(to[e],u,d+1);
}
struct qry{ int d, l, r, c; };
vector<qry> S[N]; int ans[N];
void jmp(int x, int l, int r, int c){for(int u=x;u;u=fa[u])S[u].pb((qry){d[dep[u]][x],l,r,c});
}
namespace zkw{cs int M = 1 << 17;int mn[M<<1];void init(){ memset(mn,0x3f,sizeof(mn)); }void ins(int x, int v){ for(x+=M;x;x>>=1)mn[x]=min(mn[x],v); }void clr(int x){ for(x+=M;x;x>>=1)mn[x]=INF; }int qry(int l, int r){int ans=INF; for(l+=M-1,r+=M+1;l^r^1;l>>=1,r>>=1){if(l&1^1) ans=min(ans,mn[l^1]);if(r&1) ans=min(ans,mn[r^1]);} return ans;}}
void subwork(int u, int dt){zkw::ins(u,d[dt][u]); for(int e=0;e<G[u].size();e++)subwork(G[u][e],dt);
}
void _subwork(int u){zkw::clr(u);for(int e=0;e<G[u].size();e++)_subwork(G[u][e]);
}
void work(int u){subwork(u,dep[u]);for(int i=0;i<S[u].size();i++){qry t=S[u][i];ans[t.c]=min(ans[t.c],zkw::qry(t.l,t.r)+t.d);} _subwork(u);
}
int main(){freopen("tree.in","r",stdin);freopen("tree.out","w",stdout);n=read(); zkw::init();for(int i=1,u,v,w;i<n;i++)u=read(),v=read(),w=read(),adde(u,v,w),adde(v,u,w);	work(1,0,0); m=read();for(int i=1,l,r,x; i<=m; i++){l=read(), r=read(), x=read();jmp(x,l,r,i); ans[i]=INF;} for(int i=1; i<=n; i++)if(S[i].size())work(i);for(int i=1; i<=m; i++) cout << ans[i] << '\n';return 0;
}

C C C

  • 枚举点积角度可以死去
  • 考虑一个等价的过程,枚举一条边以及角度,积有贡献的点集的面积

在这里插入图片描述

  • 变成积一个前缀的面积,发现每次要处理的就是 ∫ S B C D d C \int S_{BCD}\text{d}C SBCDdC

在这里插入图片描述

  • B C sin ⁡ B + C = A B sin ⁡ C \frac{BC}{\sin B+C}=\frac{AB}{\sin C} sinB+CBC=sinCAB, S = A B ∗ B C ∗ sin ⁡ B = t ∗ sin ⁡ C sin ⁡ B + C S=AB*BC*\sin B=t*\frac{\sin C}{\sin B+C} S=ABBCsinB=tsinB+CsinC 其中 t t t 为常量,考虑积分:
    ∫ 0 R sin ⁡ C sin ⁡ B + C d C = cos ⁡ B ∗ R − sin ⁡ B ∫ B R + B cos ⁡ C sin ⁡ C d C \int_0^{R}\frac{\sin C}{\sin B+C}\text{d}C\\ =\cos B *R- \sin B\int_B^{R+B}\frac{\cos C}{\sin C}\text{d}C 0RsinB+CsinCdC=cosBRsinBBR+BsinCcosCdC
    ∫ cos ⁡ x sin ⁡ x d x = ∫ 1 sin ⁡ x d sin ⁡ x = ln ⁡ sin ⁡ x \int \frac{\cos x}{\sin x}\text{d}x=\int \frac{1}{\sin x}\text{d}\sin x=\ln \sin x sinxcosxdx=sinx1dsinx=lnsinx
#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define fi first
#define se second
using namespace std;
namespace IO{cs int Rlen=1<<22|1;inline char gc(){static char buf[Rlen],*p1,*p2;(p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin));return p1==p2?EOF:*p1++;} int read(){int x=0; char c=gc(); bool f=false;while(!isdigit(c)) f=c=='-', c=gc();while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48), c=gc();return f?-x:x;}
} using namespace IO;
cs int N = 3e3 + 50;
cs double eps = 1e-8, PI = acos(-1.0);
int sgn(double a){ return (a>eps) - (a<-eps); }
struct pnt{double x, y; pnt(double _x=0, double _y=0){ x=_x; y=_y; }void input(){ x=read(); y=read(); }void output(){ cout << x <<" " << y << '\n'; }pnt operator + (cs pnt &a){ return pnt(x+a.x,y+a.y); }pnt operator - (cs pnt &a){ return pnt(x-a.x,y-a.y); }double operator * (cs pnt &a){ return x*a.y-y*a.x; }pnt operator * (cs double &a){ return pnt(x*a,y*a); }double Len(){ return x * x + y * y; }double len(){ return sqrt(x*x+y*y); }double ang(){ return atan2(y,x); }
};
int n; pnt p[N]; double ans[N];
double ang(pnt a, pnt b, pnt c){return acos(((b-a).Len()+(c-b).Len()-(c-a).Len())/(2*(c-b).len()*(b-a).len()));
}
int main(){#ifdef FSYolandafreopen("1.in","r",stdin);#endifn=read();for(int i=1; i<=n; i++) p[i].input(),p[i+n]=p[i]; double S=0;for(int i=1; i<=n; i++)S+=p[i]*p[i+1];for(int i=1; i<=n; i++){double now = 0;for(int j=i+1; j<i+n-1; j++){double a = ang(p[j],p[i],p[j+1]);double b = ang(p[i],p[j],p[j+1]);ans[i] += a * now + (p[i]-p[j]).Len() * sin(b) * (a * cos(b) - sin(b) * (log(fabs(sin(a+b))) - log(fabs(sin(b)))));now += (p[j]-p[i]) * (p[j+1]-p[i]);}}for(int i=1; i<=n; i++){double Ans = ans[i] - ans[i%n+1];Ans += (PI - ang(p[i+n-1],p[i],p[i+1])) * S;printf("%.8lf\n",Ans/S/PI/2);} return 0;} 

这篇关于【省选模拟】20/06/05的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/658655

相关文章

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

hdu4431麻将模拟

给13张牌。问增加哪些牌可以胡牌。 胡牌有以下几种情况: 1、一个对子 + 4组 3个相同的牌或者顺子。 2、7个不同的对子。 3、13幺 贪心的思想: 对于某张牌>=3个,先减去3个相同,再组合顺子。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOExcepti

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

忽略某些文件 —— Git 学习笔记 05

忽略某些文件 忽略某些文件 通过.gitignore文件其他规则源如何选择规则源参考资料 对于某些文件,我们不希望把它们纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常它们都是些自动生成的文件,比如日志文件、编译过程中创建的临时文件等。 通过.gitignore文件 假设我们要忽略 lib.a 文件,那我们可以在 lib.a 所在目录下创建一个名为 .gi

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param