日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

G - Best ACMer Solves the Hardest Problem Gym - 101955G

發(fā)布時(shí)間:2023/12/3 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 G - Best ACMer Solves the Hardest Problem Gym - 101955G 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

G - Best ACMer Solves the Hardest Problem Gym - 101955G

題意:

我們需要建立一個(gè)數(shù)據(jù)庫(kù)以支持實(shí)時(shí)查詢和修改。這個(gè)數(shù)據(jù)庫(kù)中的記錄是點(diǎn)坐標(biāo) (x,y) 和其權(quán)值 w。查詢與修改操作可以表示為

1 x y w,在 (x,y) 處插入一個(gè)新的點(diǎn),我們保證在插入之前該位置沒(méi)有點(diǎn)。
2 x y,刪除 (x,y) 處的點(diǎn),我們保證在刪除之前該位置存在一點(diǎn)。
3 x y k w,對(duì)于每一個(gè)到 (x,y) 的歐幾里得距離為 sqrt(k) 的點(diǎn),給它的權(quán)值增加 w。
4 x y k,對(duì)于每一個(gè)到 (x,y) 的歐幾里得距離為 sqrt(k) 的點(diǎn),求出它們權(quán)值 w 的和。
其中 (x0,y0) 與 (x1,y1) 的歐幾里得距離為 sqrt((x0 - x1)2 + (y0 - y1)2)
為了讓所有 x 和 y 動(dòng)態(tài),我們引入變量 lastans 來(lái)表示上一次查詢的結(jié)果,其初始值為 0。對(duì)于每一個(gè)操作中的 x 和 y,它們的真實(shí)值分別為 (x+lastans)%6000+1 和 (y+lastans)%6000+1
0 ≤ k ≤ 107, 1 ≤ x, y, w ≤ 6000

題解:

如果對(duì)于每次查詢,我們先搜與該點(diǎn)歐幾里得距離為len的點(diǎn),肯定不行,我們可以預(yù)處理,先算出與原點(diǎn)距離在1e7以內(nèi)的所有點(diǎn),并用相應(yīng)的距離存儲(chǔ),當(dāng)之后要對(duì)(x,y)查詢時(shí),我們可以直接調(diào)用過(guò)來(lái)
比如(x1,y1)距離原點(diǎn)為k,說(shuō)明(x1)2+(y1)2=k,那么(x-(t * x1+x))2+(y-(t * y1+y))2=k
t可以是-1或者1,其實(shí)也就是x和y分別向四個(gè)方向伸的點(diǎn)

代碼:

#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的點(diǎn) {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; }

總結(jié)

以上是生活随笔為你收集整理的G - Best ACMer Solves the Hardest Problem Gym - 101955G的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。