【BZOJ3616】War
来源:互联网 发布:网络 在线客服 编辑:程序博客网 时间:2024/06/05 14:22
Description
小x所在的世界正在经历一场在k个阵营之间的战争。每个阵营有若干个炮塔,每个炮塔由攻击系统和防御系统组成。第i个炮塔可以攻击到离它欧几里德距离小于等于ri 或者曼哈顿距离小于等于ai的炮塔,被攻击到的炮塔防御系统就会崩溃,同一联盟的炮塔不会被攻击到。每次会随机选择一个炮塔攻击它能打到的所有炮塔,问进行m轮后期望剩下多少个阵营,使得这些阵营拥有的炮塔的防御系统全部完好。防御系统崩溃的炮塔还是会被打到的。值得注意的是,如果一个联盟没有任何炮塔,那么不管怎样它都是完好的。
Input
输入文件第一行有三个整数n、m、k,分别表示炮塔数目、攻击轮数以及联盟个数。 接下去n行每行有五个正整数xi、yi、ri、ai、pi,其中xi、yi表示炮塔坐标,p表示炮塔所属于阵营。
Output
输出一行一个实数表示答案,你的输出与标准输出的误差在1e-3以内会被认为是正确的。
Sample Input
2 2 3
0 0 2 2 1
1 1 2 2 2
Sample Output
1.500
HINT
100%的数据, 0 <= n、m、k <= 35000,1 <= pi <= k,其余所有数字均非负且小于10000,保证在数据生成时不考虑一个点的具体位置,而将它的横纵坐标分开考虑。
Source
2014年国家集训队十五人互测 鸣谢佚名上传
考虑使用bitset,在kdtree的每个节点维护一个,然后连边,
然后发现其实概率论才是这个题考察的主要内容(雾
注意bitset不能写结构体里面..因为每个bitset都是35000的,然后如果一坨放一起做swap…场面太美,直接TLE
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<bitset>#define MAXN 35002#define Dnum 2#define GET (ch>='0'&&ch<='9')using namespace std;inline void in(int &x){ char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar();}double ans;int N,M,K,n,root,top,tp;int r[MAXN],a[MAXN],p[MAXN],id[MAXN];bool cmp_d;struct edge { int to; edge *next; }e[10000000],*prev[MAXN],E[MAXN<<1],*Prev[MAXN];inline void insert(int u,int v) { e[++top].to=v;e[top].next=prev[u];prev[u]=&e[top]; }inline void insert1(int u,int v) { E[++tp].to=v;e[tp].next=Prev[u];Prev[u]=&E[tp]; }struct KDtree{ int d[Dnum],ch[2],minn[Dnum],maxn[Dnum],fa; inline void init() { for (int i=0;i<Dnum;++i) minn[i]=maxn[i]=d[i]; } inline bool operator < (const KDtree& a)const { return d[cmp_d]<a.d[cmp_d]; }}tree[MAXN];bitset<MAXN> P[MAXN];inline void push_up(int rt){ for (int i=0;i<2;++i) if (tree[rt].ch[i]) { int x=tree[rt].ch[i]; for (int j=0;j<Dnum;++j) tree[rt].minn[j]=min(tree[rt].minn[j],tree[x].minn[j]), tree[rt].maxn[j]=max(tree[rt].maxn[j],tree[x].maxn[j]); }}int rebuild(int l=1,int r=n,bool d=0,int f=0){ cmp_d=d;int mid=(l+r)>>1;nth_element(tree+l,tree+mid,tree+r+1); id[tree[mid].fa]=mid;tree[mid].fa=f;tree[mid].init(); if (l!=mid) tree[mid].ch[0]=rebuild(l,mid-1,d^1,mid); if (r!=mid) tree[mid].ch[1]=rebuild(mid+1,r,d^1,mid); return push_up(mid),mid;}inline int sqr(int x) { return x*x; }void calc(int rt,int id,int x,int y){ if (sqr(max(max(x-tree[rt].maxn[0],tree[rt].minn[0]-x),0))+sqr(max(max(y-tree[rt].maxn[1],tree[rt].minn[1]-y),0))>r[id] && max(tree[rt].minn[0]-x,0)+max(x-tree[rt].maxn[0],0)+max(tree[rt].minn[1]-y,0)+max(y-tree[rt].maxn[1],0)>a[id]) return; if (max(sqr(x-tree[rt].minn[0]),sqr(x-tree[rt].maxn[0]))+max(sqr(y-tree[x].minn[1]),sqr(y-tree[x].maxn[1]))<=r[id] || max(abs(x-tree[rt].maxn[0]),abs(tree[x].minn[0]-x))+max(abs(y-tree[x].maxn[1]),abs(tree[x].maxn[1]-y))<=a[id]) { P[rt][id]=1;return; } for (int i=0;i<2;++i) if (tree[rt].ch[i]) calc(tree[rt].ch[i],id,x,y); }void solve(int rt=root){ for (int i=0,x=0;i<2;++i) if ((x=tree[rt].ch[i])) P[x]|=P[rt],solve(x); for (edge *i=prev[rt];i;i=i->next) P[rt][i->to]=1;}int main(){ in(N);in(M);in(K);n=N;int x; for (int i=1;i<=N;i++) { tree[i].fa=i;in(tree[i].d[0]);in(tree[i].d[1]); in(r[i]);in(a[i]);in(p[i]); insert1(p[i],i); } root=rebuild(); for (int i=1;i<=N;i++) calc(root,i,tree[id[i]].d[0],tree[id[i]].d[1]); for (solve(),x=1;x<=K;x++) { bitset<MAXN> tmp=0; for (edge *i=Prev[x];i;i=i->next) tmp|=P[i->to]; for (edge *i=Prev[x];i;i=i->next) tmp[i->to]=0; int cnt=tmp.count();ans+=pow(1-1.0*cnt/N,M); } printf("%.6f\n",ans);}
- 【BZOJ3616】War
- 【BZOJ3616】War,KD树+bitset压位
- War
- .war
- .war
- War
- war
- exploded war VS war
- Original War
- 做war
- jar war |
- 生成.war
- 打war
- WAR文件
- JAR WAR
- .war文件
- war maven
- war包
- 【BZOJ2850】巧克力王国
- Linux热补丁的实现
- 【三层转七层,你还在困惑吗?】
- 【fzoj】Problem 2020 组合(组合数取模)
- 【CQOI 2016】不同的最小割
- 【BZOJ3616】War
- 利用后缀数组构造后缀树
- Java版打飞机小游戏
- 【IPSC2015】【BZOJ4154】Generating Synergy
- iOS学习笔记之手动内存管理(一)
- 【Redis源码剖析】 - Redis数据类型之有序集合zset
- 【SDOI2010】【BZOJ1941】Hide and Seek
- 浅析最大二分图匹配算法中记录数组book的真实作用
- spring源码解析