第10周总结
总结:三天集训,前两天就做出了2个题(好像是最多两个来着),第三天4个,还有一个超时,木有找到规律。
A类:http://codeforces.com/gym/101955/problem/G
参考博客:https://www.cnblogs.com/hua-dong/p/10363254.html
题意:在二维平面上四种操作: 1,加一个带权的点; 2,删去一个点; 3,给一个点周围欧几里得距离为sqrt(k)的存在的点点权都加w; 4,查询一个到点欧几里得距离为sqrtk的点权和。
思路:开始看到题的第一反应是线段树区间问题,然后发现是求符合的点的个数,就不会做了。
题解是暴力模拟(由于所求的点不会太多),在维护整个图的状态的时候,用的是map,用struct会超时。
代码:
#include<cstdio> #include<iostream> #include<vector> #include<map> using namespace std; #define pii pair<int,int> #define mp make_pair typedef long long ll; /* 无需写出型别, 就可以生成一个pair对象 std::make_pair(42, '@'); 两者相等 std::pair<int, char>(42, '@') */ const int maxm=10000000; const int maxn=6010; ll a[maxn][maxn]; int vis[maxn][maxn]; vector<pii>vv[maxm+10]; int n,m,x,y,k,w,ca; void bb(int x,int y,int w){ if(x<0||x>6000||y<0||y>6000) return; if(vis[x][y]=ca) a[x][y]+=w; } void add(int x,int y,int w){ if(vis[x][y]!=ca) a[x][y]=0,vis[x][y]=ca; a[x][y]+=w; } void add2(int x,int y,int k,int w){ for(int i=0;i<vv[k].size();i++){ int dx=vv[k][i].first,dy=vv[k][i].second; bb(x+dx,y+dy,w); if(dx!=0) bb(x-dx,y+dy,w); if(dy!=0) bb(x+dx,y-dy,w); if(dx!=0&&dy!=0) bb(x-dx,y-dy,w); } } void del(int x,int y){ vis[x][y]=0; a[x][y]=0; } int query(int x,int y){ if(x<0||x>6000||y<0||y>6000) return 0; if(vis[x][y]=ca) return a[x][y]; return 0; } ll queryy(int x,int y,int k){ ll res=0; for(int i=0;i<vv[k].size();i++){ int dx=vv[k][i].first,dy=vv[k][i].second; res+=query(x+dx,y+dy); if(dx!=0) res+=query(x-dx,y+dy); if(dy!=0) res+=query(x+dx,y-dy); if(dx!=0&&dy!=0) res+=query(x-dx,y-dy); } return res; } int main(){ int t; for(int i=1;i<=3300;i++){ for(int j=1;j<=3300;j++){ if(i*i+j*j>maxm) break; vv[i*i+j*j].push_back(mp(i,j)); } } cin>>t; while(t--){ ll ans=0; ca++; cin>>n>>m; printf("Case #d:\n",ca); for(int i=0;i<n;i++){ cin>>x>>y>>w; add(x,y,w); } for(int i=0;i<m;i++){ int a; cin>>a>>x>>y; x=(x+ans)%6000+1; y=(y+ans)%6000+1; if(a==1){ cin>>w; add(x,y,w); } else if(a==2){ del(x,y); } else if(a==3){ cin>>k>>w; add2(x,y,k,w); } else{ cin>>k; ans=queryy(x,y,k); printf("%lld\n",ans); } } } return 0; }
B类:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3785
题意:输入N,求 11 + 22 + 33 + ... + NN days?
思路:打表求循环(294个,真多) 规律参考博客:https://www.cnblogs.com/Simon-X/p/5110328.html
代码:
#include<cstdio> #include<iostream> using namespace std; int day[294] = { 0, 1, 5, 4, 1, 4, 5, 5, 6, 0, 4, 6, 0, 6, 6, 0, 2, 0, 1, 6, 0, 0, 1, 5, 6, 3, 0, 6, 6, 0, 1, 4, 6, 5, 6, 6, 0, 2, 4, 5, 0, 6, 6, 0, 4, 3, 0, 3, 4, 4, 5, 6, 3, 5, 6, 5, 5, 6, 1, 6, 0, 5, 6, 6, 0, 4, 5, 2, 6, 5, 5, 6, 0, 3, 5, 4, 5, 5, 6, 1, 3, 4, 6, 5, 5, 6, 3, 2, 6, 2, 3, 3, 4, 5, 2, 4, 5, 4, 4, 5, 0, 5, 6, 4, 5, 5, 6, 3, 4, 1, 5, 4, 4, 5, 6, 2, 4, 3, 4, 4, 5, 0, 2, 3, 5, 4, 4, 5, 2, 1, 5, 1, 2, 2, 3, 4, 1, 3, 4, 3, 3, 4, 6, 4, 5, 3, 4, 4, 5, 2, 3, 0, 4, 3, 3, 4, 5, 1, 3, 2, 3, 3, 4, 6, 1, 2, 4, 3, 3, 4, 1, 0, 4, 0, 1, 1, 2, 3, 0, 2, 3, 2, 2, 3, 5, 3, 4, 2, 3, 3, 4, 1, 2, 6, 3, 2, 2, 3, 4, 0, 2, 1, 2, 2, 3, 5, 0, 1, 3, 2, 2, 3, 0, 6, 3, 6, 0, 0, 1, 2, 6, 1, 2, 1, 1, 2, 4, 2, 3, 1, 2, 2, 3, 0, 1, 5, 2, 1, 1, 2, 3, 6, 1, 0, 1, 1, 2, 4, 6, 0, 2, 1, 1, 2, 6, 5, 2, 5, 6, 6, 0, 1, 5, 0, 1, 0, 0, 1, 3, 1, 2, 0, 1, 1, 2, 6, 0, 4, 1, 0, 0, 1, 2, 5, 0, 6, 0, 0, 1, 3, 5, 6, 1, 0 }; string s[7]= {"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; int main(){ int t, a; scanf("%d", &t); while (t--){ scanf("%d", &a); printf("%s\n",s[day[a % 294]].c_str());//cout会超时。 } return 0; }