CF Gym 101955G Best ACMer Solves the Hardest Problem
Posted yokel062
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF Gym 101955G Best ACMer Solves the Hardest Problem相关的知识,希望对你有一定的参考价值。
链接:https://codeforces.com/gym/101955/problem/G
题意:在二维平面上四种操作: 1,加一个带权的点; 2,删去一个点; 3,给一个点周围欧几里得距离为sqrt(k)的存在的点点权都加w; 4,查询一个到点欧几里得距离为sqrtk的点权和。
x, y<6000, k<1e7, sigma(询问次数)<1e6,time:12s
题解:原本以为是数据结构,发现距离为k的x,y其实不多,直接存vector<pii>dis[maxk]暴力即可。
注意:要判断nx,ny范围是否溢出,还有就是能不用memset尽量不要用,会超时。
#include <bits/stdc++.h> using namespace std; typedef pair<int, int> pii; const int mod=6e3; const int maxk=1e7+5; const int maxn=6e3+5; vector<pii> dis[maxk]; int vis[maxn][maxn], val[maxn][maxn]; int T, kase=0; void pre_dis() { for(int x=0; x<=3200; x++) for(int y=0; y<=3200; y++) { if(x*x+y*y>maxk) continue; dis[x*x+y*y].push_back(pii(x, y)); } } void ins(int x, int y, int w) { val[x][y]=w; vis[x][y]=kase; } void del(int x, int y) { vis[x][y]=false; } bool check(int x, int y) { if(x<0 || x>6000 || y<0 || y>6000) return false; if(vis[x][y]==kase) return true; return false; } void add(int x, int y, int k, int w) { for(int i=0; i<dis[k].size(); i++) { int dx=dis[k][i].first, dy=dis[k][i].second; if(check(x+dx,y+dy)){ val[x+dx][y+dy]+=w; } if(dx!=0 && check(x-dx,y+dy)){ val[x-dx][y+dy]+=w; } if(dy!=0 && check(x+dx,y-dy)){ val[x+dx][y-dy]+=w; } if(dx!=0&&dy!=0 && check(x-dx,y-dy)){ val[x-dx][y-dy]+=w; } } } long long ask(int x, int y, int k) { long long res=0; for(int i=0; i<dis[k].size(); i++) { int dx=dis[k][i].first, dy=dis[k][i].second; if(check(x+dx,y+dy)){ res+=val[x+dx][y+dy]; } if(dx!=0 && check(x-dx,y+dy)){ res+=val[x-dx][y+dy]; } if(dy!=0 && check(x+dx,y-dy)){ res+=val[x+dx][y-dy]; } if(dx!=0&&dy!=0 && check(x-dx,y-dy)){ res+=val[x-dx][y-dy]; } } return res; } int main() { //freopen("in.txt", "r", stdin); pre_dis(); for(scanf("%d", &T); T--; ) { printf("Case #%d: ", ++kase); //memset(vis, false, sizeof(vis)); 加上这句会超时 int n, m; long long lastans=0; scanf("%d%d", &n, &m); for(int i=0; i<n; i++) { int x, y, w; scanf("%d%d%d", &x, &y, &w); ins(x, y, w); } for(int i=0; i<m; i++) { int cmd, x, y, w, k; scanf("%d%d%d", &cmd, &x, &y); x=(x+lastans)%mod+1; y=(y+lastans)%mod+1; if(cmd==1){ scanf("%d", &w); ins(x, y, w); } else if(cmd==2){ del(x, y); } else if(cmd==3){ scanf("%d%d", &k, &w); add(x, y, k, w); } else if(cmd==4){ scanf("%d", &k); printf("%I64d ", lastans=ask(x, y, k)); } } } return 0; }
以上是关于CF Gym 101955G Best ACMer Solves the Hardest Problem的主要内容,如果未能解决你的问题,请参考以下文章
cf gym gym 101177 A - Anticlockwise Motion