BZOJ 1062 糖果雨
http://www.lydsy.com/JudgeOnline/problem.php?id=1062
思路:找到平行四边形以后,变换坐标:y->y-kx,k为斜率,这样变成了矩形,然后只要二维树状数组就行了、
注意可能因为取余的原因,把一个平行四边形拆成两半
1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 int len2,len,len4,n; 7 int tr[2][2005][4005]; 8 int x[4000005],y[4000005]; 9 int lowbit(int X){ 10 return (X)&(-X); 11 } 12 int read(){ 13 int t=0,f=1;char ch=getchar(); 14 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 15 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 16 return t*f; 17 } 18 void add(int k,int x,int y,int c){ 19 x++;y++; 20 for (int i=x;i<=len2;i+=lowbit(i)) 21 for (int j=y;j<=len4;j+=lowbit(j)) 22 tr[k][i][j]+=c; 23 } 24 int sum(int k,int x,int y){ 25 if (x<0||y<0) return 0; 26 x++;y++; 27 int ans=0; 28 if (x>len2) x=len2+1; 29 if (y>len4) y=len4+1; 30 for (int i=x;i;i-=lowbit(i)) 31 for (int j=y;j;j-=lowbit(j)) 32 ans+=tr[k][i][j]; 33 return ans; 34 } 35 int sum(int k,int x1,int y1,int x2,int y2){ 36 return sum(k,x2,y2)+sum(k,x1-1,y1-1)-sum(k,x2,y1-1)-sum(k,x1-1,y2); 37 } 38 int main(){ 39 n=read();len=read();len2=len<<1;len4=len2<<1; 40 while (n--){ 41 int opt=read(); 42 if (opt==1){ 43 int t=read(),c=read(),l=read(),r=read(),d=read(); 44 x[c]=(t-d*l+len2)%len2; 45 y[c]=r-l; 46 add(0,x[c],y[c]+x[c],1); 47 add(1,x[c],y[c]-x[c]+len2,1); 48 }else 49 if (opt==2) 50 { 51 int t=read(),l=read(),r=read(); 52 t%=len2; 53 int k=(r==len); 54 int ans=sum(0,t,l+t,r+t,len4)+sum(0,0,l+t-len2,r+t-len2-k,len4) 55 +sum(1,t-r+len2+k,l-t,len2,len4)+sum(1,t-r,l-t+len2,t-1,len4); 56 printf("%d\n",ans); 57 }else{ 58 int t=read(),c=read(); 59 add(0,x[c],y[c]+x[c],-1); 60 add(1,x[c],y[c]-x[c]+len2,-1); 61 } 62 } 63 64 }