这题卡了四五天了,从开始看题目就蛋疼了,看了不知道多少遍,再与队友分析了一下,总算明白了题意。
题意及思路:首先给出m组s0,t0,ds,dt,k; 由公式算出m*k个点;
然后给出p组a0,b0,c0,d0,da,db,dc,dd,q; 由公式算出q个矩形;
对于每个矩形是否有点在其内。
用线段树扫描线统计每一个点左下方点的个数,然后用标记映射到每一个矩形;
最后再拿统计矩形内点数( 右上+左下-右下-左上 )。
ACcode:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using std::sort;
using std::unique;
const int msize=1111111;
const int ksize=400;
const LL MOD=200904040963LL;
LL m7[ksize],res;
int sum[msize<<2];
int q[ksize],re[ksize];
int num[msize],X[msize];
struct Point
{
int x,y;
int f;
Point() {}
Point(int a,int b,int c):x(a),y(b),f(c) {}
bool operator <(const Point &cmp) const{
if (y!=cmp.y) return y<cmp.y;
if (x!=cmp.x) return x<cmp.x;
return f<cmp.f;
}
} point[msize];
void Init()
{
m7[0]=1;
for (int i=1; i<=345; i++)
m7[i]=(m7[i-1]*7)%MOD;
}
int Max(int a1,int a2)
{
return a1>a2?a1:a2;
}
int Min(int a1,int a2)
{
return a1<a2?a1:a2;
}
int Fin(int key,int len)
{
int l=0,r=len;
while (l<=r)
{
int m=(l+r)>>1;
if (X[m]==key) return m;
else if (X[m]<key) l=m+1;
else r=m-1;
}
return -1;
}
void build(int rt,int l,int r)
{
sum[rt]=0;
if (l==r) return ;
int m=(l+r)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
}
void update(int rt,int l,int r,int pos)
{
if (l==r)
{
sum[rt]++;
return ;
}
int m=(l+r)>>1;
if (pos<=m) update(rt<<1,l,m,pos);
else update(rt<<1|1,m+1,r,pos);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
int query(int rt,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return sum[rt];
int m=(l+r)>>1,ans=0;
if (L<=m) ans+=query(rt<<1,l,m,L,R);
if (R>m) ans+=query(rt<<1|1,m+1,r,L,R);
return ans;
}
int main()
{
Init();
int i,j,n,m;
int x1,y1,x2,y2,p;
int s0,t0,ds,dt,k;
int cnt,len,pos,top;
int a0,b0,c0,d0,da,db,dc,dd;
while (~scanf("%d %d",&n,&m))
{
cnt=len=top=0;
for (i=0; i<m; i++)
{
scanf("%d%d%d%d%d",&s0,&t0,&ds,&dt,&k);
for (j=0; j<k; j++,top++)
{
X[len++]=s0;
point[top]=Point(s0,t0,-1);
s0=(s0+ds+n)%n,t0=(t0+dt+n)%n;
}
}
scanf("%d",&p);
for (i=0; i<p; i++)
{
scanf("%d%d%d%d%d%d%d%d%d",&a0,&b0,&c0,&d0,&da,&db,&dc,&dd,q+i);
for (j=0; j<q[i]; j++)
{
x1=Min(a0,b0)-1,x2=Max(a0,b0);
y1=Min(c0,d0)-1,y2=Max(c0,d0);
X[len++]=x1,X[len++]=x2;
point[top++]=Point(x1,y1,cnt),cnt++;
point[top++]=Point(x1,y2,cnt),cnt++;
point[top++]=Point(x2,y1,cnt),cnt++;
point[top++]=Point(x2,y2,cnt),cnt++;
a0=(a0+da+n)%n,b0=(b0+db+n)%n;
c0=(c0+dc+n)%n,d0=(d0+dd+n)%n;
}
}
sort(X,X+len);
sort(point,point+top);
len=unique(X,X+len)-X-1;
build(1,0,len);
for (i=0; i<top; i++)
{
k=point[i].f;
pos=Fin(point[i].x,len);
if (k<0) update(1,0,len,pos);
else num[k]=query(1,0,len,0,pos);
}
for (t0=i=0; i<p; i++)
{
for (j=0; j<q[i]; j++)
{
k=num[t0+3]+num[t0]-num[t0+1]-num[t0+2];
re[j]=k>0?1:0;
t0+=4;
}
if (q[i]>20)
{
for (res=j=0; j<q[i]; j++)
res=(res+re[j]*m7[j])%MOD;
printf("%lld",res);
}
else
for (j=0; j<q[i]; j++) printf("%d",re[j]);
puts("");
}
}
return 0;
}