http://codeforces.com/gym/101955/problem/G
给出一个6000*6000的坐标系,有四种操作,一是加入放置一个点到某个空格子上,二是从某个有点的格子移走一个点,三是将距离(x,y)距离为根号k的点权值加上w,四是询问距离(x,y)距离为根号k的点权值总和。
由于k都是整数,而在圆上的整数点很少,所以想到,A^2+B^2=K^2,处理出所有(A,B)对于每个A^2+B^2。1,2操作就很简单了,3,4操作的话直接暴力从K对应的(A,B)暴力查找合法的点。
各种TLE,WA,这个C数组大小6000*6000,每次都memset的话就会T,只能用一个vector记录下本次涉及到的点最后清零。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<map> 5 #include<set> 6 #include<stack> 7 #include<deque> 8 #include<bitset> 9 #include<unordered_map> 10 #include<unordered_set> 11 #include<queue> 12 #include<cstdlib> 13 #include<ctype.h> 14 #include<ctime> 15 #include<functional> 16 #include<algorithm> 17 #include<bits/stdc++.h> 18 using namespace std; 19 #define LL long long 20 #define pii pair<int,int> 21 #define mp make_pair 22 #define pb push_back 23 #define fi first 24 #define se second 25 #define inf 0x3f3f3f3f 26 #define debug puts("debug") 27 #define mid ((L+R)>>1) 28 #define lc (id<<1) 29 #define rc (id<<1|1) 30 const int maxn=10010; 31 const int maxm=50050; 32 const double PI=acos(-1.0); 33 const double eps=1e-6; 34 const LL mod=1e9+7; 35 LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);} 36 LL lcm(LL a,LL b){return a/gcd(a,b)*b;} 37 LL qpow(LL a,LL b,LL c){LL r=1; for(;b;b>>=1,a=a*a%c)if(b&1)r=r*a%c;return r;} 38 struct Edge{int v,w,next;}; 39 40 template<class T> 41 ostream & operator<<(ostream &out,vector<T>&v){ 42 for(auto x:v)cout<<x<<' '; 43 return out; 44 } 45 void read(LL &n){ 46 n=0; char c=getchar(); 47 while(c<'0'||c>'9')c=getchar(); 48 while(c>='0'&&c<='9') n=(n<<3)+(n<<1)+(c-'0'),c=getchar(); 49 } 50 LL C[6005][6005]; 51 LL dir[4][2]={1,1,1,-1,-1,1,-1,-1}; 52 bool ojbk(LL x,LL y){ 53 if(x<1||x>6000||y<1||y>6000||C[x][y]==0)return 0; 54 return 1; 55 } 56 #define pll pair<LL,LL> 57 const LL MAX=10000000+15; 58 vector<pll> cl,a[MAX]; 59 void AC(){ 60 LL T,n,m,cas=0; 61 scanf("%lld",&T); 62 while(T--){ 63 scanf("%lld%lld",&n,&m); 64 LL last=0; 65 LL x,y,w,k,op; 66 for(int i=1;i<=n;++i){ 67 scanf("%lld%lld%lld",&x,&y,&w); 68 cl.pb(mp(x,y)); 69 C[x][y]+=w; 70 } 71 printf("Case #%lld:\n",++cas); 72 while(m--){ 73 scanf("%lld%lld%lld",&op,&x,&y); 74 x=(x+last)%6000+1; 75 y=(y+last)%6000+1;cl.pb(mp(x,y)); 76 if(op==1){ 77 scanf("%lld",&w); 78 C[x][y]=w; 79 80 } 81 else if(op==2){ 82 C[x][y]=0; 83 } 84 else if(op==3){ 85 scanf("%lld%lld",&k,&w); 86 set<pll>S; 87 for(auto v:a[k]){ 88 for(int i=0;i<4;++i){ 89 LL sx=x+v.fi*dir[i][0],sy=y+v.se*dir[i][1]; 90 if(ojbk(sx,sy))S.insert(mp(sx,sy)); 91 } 92 93 }for(auto o:S){ 94 C[o.fi][o.se]+=w; 95 } 96 } 97 else{ 98 scanf("%lld",&k); 99 LL ans=0; 100 set<pll>S; 101 for(auto v:a[k]){ 102 103 for(int i=0;i<4;++i){ 104 LL sx=x+v.fi*dir[i][0],sy=y+v.se*dir[i][1]; 105 if(ojbk(sx,sy))S.insert(mp(sx,sy)); 106 } 107 108 }for(auto o:S){ 109 ans+=C[o.fi][o.se]; 110 } 111 printf("%lld\n",ans); 112 last=ans; 113 } 114 } 115 for(auto v:cl)C[v.fi][v.se]=0; 116 cl.clear(); 117 } 118 } 119 int main(){ 120 for(LL i=0;i<=6000;++i){ 121 for(LL j=0;j<=6000;++j){ 122 if(i*i+j*j>MAX-15)break; 123 a[i*i+j*j].pb(mp(i,j)); 124 } 125 } 126 AC(); 127 return 0; 128 } 129 /* 130 131 1 132 3 6 133 2999 3000 1 134 3001 3000 1 135 3000 2999 1 136 1 2999 3000 1 137 4 2999 2999 1 138 2 2995 2996 139 3 2995 2995 1 1 140 4 2995 2995 1 141 4 3000 3000 1 142 143 */