G - Best ACMer Solves the Hardest Problem Gym - 101955G
G - Best ACMer Solves the Hardest Problem Gym - 101955G
題意:
我們需要建立一個數據庫以支持實時查詢和修改。這個數據庫中的記錄是點坐標 (x,y) 和其權值 w。查詢與修改操作可以表示為
1 x y w,在 (x,y) 處插入一個新的點,我們保證在插入之前該位置沒有點。
2 x y,刪除 (x,y) 處的點,我們保證在刪除之前該位置存在一點。
3 x y k w,對于每一個到 (x,y) 的歐幾里得距離為 sqrt(k) 的點,給它的權值增加 w。
4 x y k,對于每一個到 (x,y) 的歐幾里得距離為 sqrt(k) 的點,求出它們權值 w 的和。
其中 (x0,y0) 與 (x1,y1) 的歐幾里得距離為 sqrt((x0 - x1)2 + (y0 - y1)2)
為了讓所有 x 和 y 動態,我們引入變量 lastans 來表示上一次查詢的結果,其初始值為 0。對于每一個操作中的 x 和 y,它們的真實值分別為 (x+lastans)%6000+1 和 (y+lastans)%6000+1
0 ≤ k ≤ 107, 1 ≤ x, y, w ≤ 6000
題解:
如果對于每次查詢,我們先搜與該點歐幾里得距離為len的點,肯定不行,我們可以預處理,先算出與原點距離在1e7以內的所有點,并用相應的距離存儲,當之后要對(x,y)查詢時,我們可以直接調用過來
比如(x1,y1)距離原點為k,說明(x1)2+(y1)2=k,那么(x-(t * x1+x))2+(y-(t * y1+y))2=k
t可以是-1或者1,其實也就是x和y分別向四個方向伸的點
代碼:
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<string> #include<iostream> #include<map> #include<vector> #include<set> #include<queue> using namespace std; typedef long long ll;const int maxv=1e7+10; const int maxn=6006; int n,m; typedef pair<int,int> pp; vector<pp >v[maxv],cc; int mp[maxn][maxn]; ll lastans; int poww[maxv]; set<pair<int,int> >cnt; set<pair<int,int> >::iterator it; int dir[4][2]={{1,1},{1,-1},{-1,1},{-1,-1}};void init() {for(int i=0;i<=6000;i++){for(int j=0;j<=6000;j++){if(i*i+j*j<=1e7){v[i*i+j*j].push_back(make_pair(i,j));}elsecontinue;}} }int judge(int x,int y) {if(x<=0||y<=0||x>6000||y>6000)return 0;return 1; }int main() {init();int t;scanf("%d",&t);for(int cas=1;cas<=t;cas++){cc.clear();printf("Case #%d:\n",cas);lastans=0;scanf("%d %d",&n,&m);for(int i=1;i<=n;i++){int x,y,w;scanf("%d %d %d",&x,&y,&w);mp[x][y]=w;cc.push_back(make_pair(x,y));}for(int qq=1;qq<=m;qq++){int op,x,y,w,k;scanf("%d",&op);if(op==1){scanf("%d %d %d",&x,&y,&w);x=(x+lastans)%6000+1;y=(y+lastans)%6000+1;mp[x][y]=w;cc.push_back(make_pair(x,y));}else if(op==2){scanf("%d %d",&x,&y);x=(x+lastans)%6000+1;y=(y+lastans)%6000+1;mp[x][y]=0;}else if(op==3){scanf("%d %d %d %d",&x,&y,&k,&w);x=(x+lastans)%6000+1;y=(y+lastans)%6000+1;cnt.clear();for(int i=0;i<v[k].size();i++)//查詢距離為k的點 {int xx=v[k][i].first;int yy=v[k][i].second;for(int j=0;j<=3;j++){int nx=xx*dir[j][0]+x;int ny=yy*dir[j][1]+y;if(judge(nx,ny)&&mp[nx][ny]!=0){cnt.insert(make_pair(nx,ny));}}}for(set<pp>::iterator it=cnt.begin();it!=cnt.end();it++){mp[it->first][it->second]+=w;}}else{scanf("%d %d %d",&x,&y,&k);x=(x+lastans)%6000+1;y=(y+lastans)%6000+1;cnt.clear();for(int i=0;i<v[k].size();i++){int xx=v[k][i].first;int yy=v[k][i].second;for(int j=0;j<=3;j++){int nx=xx*dir[j][0]+x;int ny=yy*dir[j][1]+y;if(judge(nx,ny)&&mp[nx][ny]!=-1){cnt.insert(make_pair(nx,ny));}}}ll ans=0;for(set<pp>::iterator it=cnt.begin();it!=cnt.end();it++){ans+=mp[it->first][it->second];}lastans=ans;printf("%lld\n",ans);}}for(int i=0;i<cc.size();i++){mp[cc[i].first][cc[i].second]=0;}}return 0; }總結
以上是生活随笔為你收集整理的G - Best ACMer Solves the Hardest Problem Gym - 101955G的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 鼻梁里面很重是什么原因引起的
- 下一篇: 不够24小时吃氯雷他定可以吗