标签:os io for ar 问题 line amp 算法
题目大意:
n个人的编号是从1 - n ,现在他们无序的站成一排。
第 id 号人和 id-1 id +1 号人是朋友,
朋友之间可以组成group。
一个group的值等于他们人数的平方。
然后有m次询问,问给出的l r 之间能构成group值的和的最大值的group数。
思路分析:
首先,我们面临着假设你知道这个区间有多少个group 你能知道得到最大值的时候group是怎么分配的么。
令 x = a + b
x^2 = (a+b)^2 = a^2 + 2ab + b^2
可以得到如果得到了group 那么就不要分裂,因为group在一起的才能组成最大值。
那么现在解决询问的问题。
我们用分块莫队算法直接跑。
用ex 记录哪个id的人存在了。
加入的时候通过判断左右两人是否存在。
然后仔细推一下就知道加入与删除的关系了。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define maxn 100005 using namespace std; int bel[maxn]; int block; inline void scanf_(int &num){ char in; bool neg=false; while(((in=getchar()) > '9' || in<'0') && in!='-') ; if(in=='-'){ neg=true; while((in=getchar()) >'9' || in<'0'); } num=in-'0'; while(in=getchar(),in>='0'&&in<='9') num*=10,num+=in-'0'; if(neg) num=0-num; } inline void printf_(int num){ bool flag=false; if(num<0){ putchar('-'); num=-num; } int ans[10],top=0; while(num!=0){ ans[top++]=num%10; num/=10; } if(top==0) putchar('0'); for(int i=top-1;i>=0;i--){ char ch=ans[i]+'0'; putchar(ch); } } struct node { int st,ed,ans,id; bool operator < (const node &cmp)const { return bel[st]<bel[cmp.st] || (bel[st]==bel[cmp.st] && ed<cmp.ed); } }Q[maxn]; bool cmp_id(node a,node b) { return a.id<b.id; } int a[maxn]; int ex[maxn]; void modify(int num,int &tans,int add) { if(add==1) { if(ex[num-1] && ex[num+1])tans--; else if(!ex[num-1] && !ex[num+1])tans++; } else { if(ex[num-1] && ex[num+1])tans++; else if(!ex[num-1] && !ex[num+1])tans--; } ex[num]+=add; } int main() { int T; scanf_(T); while(T--) { memset(ex,0,sizeof ex); int n,m; scanf_(n),scanf_(m); block=(int)sqrt(1.0*n); for(int i=1;i<=n;i++) { scanf_(a[i]); bel[i]=(i-1)/block+1; } for(int i=1;i<=m;i++) { scanf_(Q[i].st); scanf_(Q[i].ed); Q[i].id=i; } sort(Q+1,Q+1+m); int tans=0; for(int l=1,r=0,i=1;i<=m;i++) { if(r<Q[i].ed) { for(r=r+1;r<=Q[i].ed;r++) modify(a[r],tans,1); r--; } if(r>Q[i].ed) { for(;r>Q[i].ed;r--) modify(a[r],tans,-1); } if(l<Q[i].st) { for(;l<Q[i].st;l++) modify(a[l],tans,-1); } if(l>Q[i].st) { for(l=l-1;l>=Q[i].st;l--) modify(a[l],tans,1); l++; } Q[i].ans=tans; } sort(Q+1,Q+1+m,cmp_id); for(int i=1;i<=m;i++) { printf_(Q[i].ans); puts(""); } } return 0; }
hdu 4638 Group (莫队算法),布布扣,bubuko.com
标签:os io for ar 问题 line amp 算法
原文地址:http://blog.csdn.net/u010709592/article/details/38497773