2017 ACM Jordanian Collegiate Programming Contest
A. Chrome Tabs
当$n=1$时答案为$0$,当$k=1$或$k=n$时答案为$1$,否则答案为$2$。
- #include<cstdio>
- int T,n,k;
- int main(){
- freopen("tabs.in","r",stdin);
- scanf("%d",&T);
- while(T--){
- scanf("%d%d",&n,&k);
- if(n==1)puts("0");
- else if(k==1||k==n)puts("1");
- else puts("2");
- }
- }
B. OverCode
按题意模拟即可。
- #include<stdio.h>
- #include<iostream>
- #include<string.h>
- #include<string>
- #include<ctype.h>
- #include<math.h>
- #include<set>
- #include<map>
- #include<vector>
- #include<queue>
- #include<bitset>
- #include<algorithm>
- #include<time.h>
- using namespace std;
- void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
- #define MS(x, y) memset(x, y, sizeof(x))
- #define ls o<<1
- #define rs o<<1|1
- typedef long long LL;
- typedef unsigned long long UL;
- typedef unsigned int UI;
- template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
- template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
- const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
- template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
- int casenum, casei;
- int n;
- int a[505];
- int main()
- {
- freopen("overcode.in","r",stdin);
- scanf("%d", &casenum);
- for (casei = 1; casei <= casenum; ++casei)
- {
- scanf("%d", &n);
- for(int i = 1; i <= n; ++i)scanf("%d", &a[i]);
- sort(a + 1, a + n + 1);
- int p = 1;
- int ans = 0;
- while(p <= n - 5)
- {
- if(a[p + 5] - a[p] <= 1000)
- {
- ++ans;
- p += 6;
- }
- else p += 1;
- }
- printf("%d\n", ans);
- }
- return 0;
- }
- /*
- 【trick&&吐槽】
- 【题意】
- 【分析】
- 【时间复杂度&&优化】
- */
C. A message for you!
按题意模拟即可。
- #include<stdio.h>
- #include<iostream>
- #include<string.h>
- #include<string>
- #include<ctype.h>
- #include<math.h>
- #include<set>
- #include<map>
- #include<vector>
- #include<queue>
- #include<bitset>
- #include<algorithm>
- #include<time.h>
- using namespace std;
- void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
- #define MS(x, y) memset(x, y, sizeof(x))
- #define ls o<<1
- #define rs o<<1|1
- typedef long long LL;
- typedef unsigned long long UL;
- typedef unsigned int UI;
- template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
- template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
- const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
- template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
- int casenum, casei;
- int n;
- char s[20];
- int a[20];
- bool e[20];
- int main()
- {
- freopen("scoreboard.in","r",stdin);
- scanf("%d", &casenum);
- for (casei = 1; casei <= casenum; ++casei)
- {
- scanf("%d", &n);
- scanf("%s", s);
- MS(e, 0);
- for(int i = 0; i < n; i ++){
- e[s[i] - 'A' + 1] = 1;
- }
- for(int i = 1; i <= 13; ++i)scanf("%d", &a[i]);
- int ans = 0, tmp = 0;
- for(int i = 1; i <= 13; i ++){
- if(e[i] == 0 && a[i] > tmp){
- tmp = a[i];
- ans = i;
- }
- }
- printf("%c\n", ans + 'A' - 1);
- }
- return 0;
- }
- /*
- 【trick&&吐槽】
- 【题意】
- 【分析】
- 【时间复杂度&&优化】
- */
D. Test Cases
枚举左端点,往右枚举右端点,同时维护每个数字出现次数的奇偶性。
时间复杂度$O(n^2)$。
- #include<cstdio>
- int T,n,i,j,odd,ans,v[1000010],a[5555];
- int main(){
- freopen("cases.in","r",stdin);
- scanf("%d",&T);
- while(T--){
- scanf("%d",&n);
- for(i=1;i<=n;i++)scanf("%d",&a[i]);
- ans=0;
- for(i=1;i<=n;i++){
- for(j=i;j<=n;j++)v[a[j]]=0;
- odd=0;
- for(j=i;j<=n;j++){
- v[a[j]]?odd--:odd++;
- v[a[j]]^=1;
- if(odd==1)ans++;
- }
- }
- printf("%d\n",ans);
- }
- }
E. Robot I - Instruction Reduction
按题意模拟即可。
- #include<stdio.h>
- #include<iostream>
- #include<string.h>
- #include<string>
- #include<ctype.h>
- #include<math.h>
- #include<set>
- #include<map>
- #include<vector>
- #include<queue>
- #include<bitset>
- #include<algorithm>
- #include<time.h>
- using namespace std;
- void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
- #define MS(x, y) memset(x, y, sizeof(x))
- #define ls o<<1
- #define rs o<<1|1
- typedef long long LL;
- typedef unsigned long long UL;
- typedef unsigned int UI;
- template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
- template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
- const int N = 505, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
- template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
- int casenum, casei;
- int n, m, q;
- int y, x; char dir;
- char s[N][N];
- int f[N][N][4]; //real way
- const int dy[4] = {-1,0,1,0};
- const int dx[4] = {0,1,0,-1};
- int a[1010 * 1010];
- int Y, X, D;
- pair<int,int> ord[1010];
- int main()
- {
- freopen("reduce.in","r",stdin);
- scanf("%d", &casenum);
- for (casei = 1; casei <= casenum; ++casei)
- {
- char dir;
- scanf("%d%d%d", &n, &m, &q);
- scanf("%d%d %c", &Y, &X, &dir);
- if(dir == 'U')D = 0;
- else if(dir == 'R')D = 1;
- else if(dir == 'D')D = 2;
- else D = 3;
- int sty = Y, stx = X, stdir = D;
- for(int i = 1; i <= n; ++i)
- {
- scanf("%s", s[i] + 1);
- }
- for(int i = 2; i < n; ++i)
- {
- for(int j = 2; j < m; ++j)if(s[i][j] == '.')
- {
- for(int d = 0; d < 4; ++d)
- {
- for(int k = 0; k < 4; ++k)
- {
- int dd = (d + k) % 4;
- if(s[i + dy[dd]][j + dx[dd]] == '.')
- {
- f[i][j][d] = dd;
- break;
- }
- }
- }
- }
- }
- //printf("f:%d\n", f[3][2][1]);
- int g = 0;
- for(int i = 1; i <= q; ++i)
- {
- char op; scanf(" %c", &op);
- if(op == 'R')
- {
- D = (D + 1) % 4;
- }
- else
- {
- int step;
- scanf("%d", &step);
- while(step--)
- {
- D = f[Y][X][D];
- Y += dy[D];
- X += dx[D];
- a[++g] = D;
- }
- }
- }
- Y = sty, X = stx, D = stdir;
- //Y X D
- int o = 0;
- for(int i = 1; i <= g; ++i)
- {
- /*
- printf("step = %d, status = %d %d %d, aimdir = %d\n", i, Y, X, D, a[i]);
- printf("f[%d][%d][%d] = %d, a[i] = %d\n", Y, X, D, f[Y][X][D], a[i]);
- getchar();
- */
- for(int k = 0; k < 4; ++k)
- {
- if(f[Y][X][D] == a[i])
- {
- D = a[i];
- Y += dy[D]; X += dx[D];
- if(o && ord[o].first == 1)
- {
- ++ord[o].second;
- }
- else ord[++o] = {1, 1};
- break;
- }
- else
- {
- ord[++o] = {2, -99999999};
- D = (D + 1) % 4;
- }
- }
- }
- printf("%d\n", o);
- }
- return 0;
- }
- /*
- 【trick&&吐槽】
- 【题意】
- 【分析】
- 【时间复杂度&&优化】
- */
F. Robot II - Colorful Grid
留坑。
G. WiFi Password
枚举区间$OR$本质不同的$O(n\log w)$段区间,更新答案即可。
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- const int N=100010;
- int T,n,lim,i,j,v[N],a[N],l[N],ans;
- inline int fun(int a,int b){return a|b;}
- int main(){
- freopen("wifi.in","r",stdin);
- scanf("%d",&T);
- while(T--){
- scanf("%d%d",&n,&lim);
- ans=0;
- for(i=1;i<=n;i++)scanf("%d",&a[i]);
- for(i=1;i<=n;i++)for(v[i]=a[i],j=l[i]=i;j;j=l[j]-1){
- v[j]=fun(v[j],a[i]);
- while(l[j]>1&&fun(a[i],v[l[j]-1])==fun(a[i],v[j]))l[j]=l[l[j]-1];
- if(v[j]<=lim)ans=max(ans,i-l[j]+1);
- }
- printf("%d\n",ans);
- }
- }
H. Gas Stations
枚举去掉哪一个加油站,那么最优策略要么是在一开始插入,要么是在末尾插入,要么是将间隔最大的空段劈成两半,维护前$4$大即可快速询问。
时间复杂度$O(n)$。
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- typedef long long ll;
- const int N=100010;
- int bestside[N];
- int T,n,m,ans,i,j,q[N];
- int pre[N],nxt[N];
- char a[N];
- int w[N],cnt;
- int now[N],tmp;
- inline bool cmp(int x,int y){return x>y;}
- inline int cal(int l,int r){
- int dis=r-l-1;
- if(l==0||r==n+1)return dis;
- return (dis+1)/2;
- }
- inline int calleft(int mark){
- for(int i=2;i<=m;i++)if(mark!=q[i])return q[i]-1;
- }
- inline int calright(int mark){
- for(int i=m-1;i;i--)if(mark!=q[i])return n-q[i];
- }
- inline void gao(int l,int r){
- if(l==0||r==n+1)return;
- w[++cnt]=r-l-1;
- }
- inline void del(int l,int r){
- if(l==0||r==n+1)return;
- int dis=r-l-1;
- int i;
- for(i=1;i<=tmp;i++)if(now[i]==dis)break;
- if(i>tmp)return;
- for(;i<tmp;i++)now[i]=now[i+1];
- tmp--;
- }
- inline void add(int l,int r){
- if(l==0||r==n+1)return;
- int dis=r-l-1;
- int i;
- now[++tmp]=dis;
- sort(now+1,now+tmp+1,cmp);
- if(tmp>4)tmp--;
- }
- inline void work(int x){
- int i=pre[x],j=nxt[x];//i x j
- tmp=cnt;
- for(int _=1;_<=cnt;_++)now[_]=w[_];
- del(i,x);
- del(x,j);
- add(i,j);
- int left=calleft(x),right=calright(x);
- int maxgap=0,secgap=0;
- if(tmp>=1)maxgap=now[1];
- if(tmp>=2)secgap=now[2];
- //case 1 add one in left
- ans=min(ans,max(bestside[left],max(right,(maxgap+1)/2)));
- //case 2 add one in right
- ans=min(ans,max(left,max(bestside[right],(maxgap+1)/2)));
- //case 3 add one in maxgap
- ans=min(ans,max(max(left,right),max((maxgap/2+1)/2,(secgap+1)/2)));
- }
- int main(){
- freopen("stations.in","r",stdin);
- for(i=j=1;i<N;i++){
- while(j<i&&max(j-1,(i-j+1)/2)>max(j,(i-(j+1)+1)/2))j++;
- bestside[i]=max(j-1,(i-j+1)/2);
- //i=3 |___+
- }
- scanf("%d",&T);
- while(T--){
- scanf("%d%s",&n,a+1);
- ans=n;
- q[m=1]=0;
- for(i=1;i<=n;i++)if(a[i]=='+')q[++m]=i;
- q[++m]=n+1;
- if(m==3){
- for(i=1;i<=n;i++)ans=min(ans,max(cal(0,i),cal(i,n+1)));
- printf("%d\n",ans);
- continue;
- }
- pre[0]=0;
- nxt[n+1]=0;
- for(i=1;i<=m;i++){
- if(i>1)pre[q[i]]=q[i-1];
- if(i<m)nxt[q[i]]=q[i+1];
- }
- cnt=0;
- for(i=1;i<m;i++)gao(q[i],q[i+1]);
- sort(w+1,w+cnt+1,cmp);
- cnt=min(cnt,4);
- for(i=2;i<m;i++)work(q[i]);
- printf("%d\n",ans);
- }
- }
I. Counting Votes
留坑。
J. Efficiency Test
将环倍长,设$f[i][j]$表示在$i$点按$j$步长往右会跳到哪里,可以得到一棵树的结构,在树上DFS,询问时二分即可。
常数优化:将失败的父亲合并,同时剔除子树内不含询问的点。
时间复杂度$O(nk+n\log n)$。
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- typedef long long ll;
- const int N=200010,M=55,E=N*M;
- int Case,n,m,nn,i,j,cnt,s[N];
- int goal[N],ans[N];
- int g[E],nxt[E],f[E],q[E],t;
- bool vip[E];
- char a[N];
- inline bool canjump(int x,int y){
- if(x+y>nn)return 0;
- if(a[x+y]=='#')return 0;
- return s[x+y]-s[x-1]<=1;
- }
- inline void gao(int x){
- //printf("gao %d\n",x);
- //for(int i=2;i<=t;i++)printf("%d %d\n",q[i],w[i]);
- //[2..t]
- int y=goal[x];
- if(q[2]<y){ans[x]=-1;return;}
- int l=3,r=t,mid,o=2;
- while(l<=r){
- mid=(l+r)>>1;
- if(q[mid]>=y)l=(o=mid)+1;else r=mid-1;
- }
- ans[x]=f[t]-f[o];
- }
- void dfs(int x){
- //printf("dfs %d\n",x);
- if(!vip[x])return;
- int A=x/(m+1);
- q[++t]=A;
- f[t]=f[t-1];
- if(q[t-1]!=A)f[t]++;
- if(A&&A<=n&&x%(m+1)==m)gao(A);
- for(int i=g[x];i;i=nxt[i])dfs(i);
- t--;
- }
- int main(){
- freopen("jumps.in","r",stdin);
- scanf("%d",&Case);
- while(Case--){
- scanf("%d%d%s",&n,&m,a+1);
- //for(i=1;i<=n;i++)a[i]='.';
- //a[1]='#';
- nn=n*2;
- for(i=1;i<=n;i++)a[i+n]=a[i];
- for(i=1;i<=nn;i++)s[i]=s[i-1]+(a[i]=='#');
- //[2..m] is valid
- cnt=nn*(m+1)+m;
- for(i=0;i<=cnt;i++)g[i]=vip[i]=0;
- for(i=nn;i;i--)if(a[i]=='.'){
- int y=0;
- for(j=2;j<=m;j++){
- int x=i*(m+1)+j;
- if(canjump(i,j))y=(i+j)*(m+1)+j;
- f[x]=y;
- //printf("f[%d][%d]=%d\n",i,j,y);
- //nxt[x]=g[y];
- //g[y]=x;
- }
- int x=i*(m+1)+m;
- while(!vip[x]){
- vip[x]=1;
- x=f[x];
- }
- }
- for(i=1;i<=nn;i++)if(a[i]=='.'){
- for(j=2;j<=m;j++){
- int x=i*(m+1)+j;
- if(!vip[x])continue;
- int y=f[x];
- nxt[x]=g[y];
- g[y]=x;
- }
- }
- for(i=j=1;i<=n;i++){
- while(s[j]-s[i-1]<s[n])j++;
- goal[i]=j;//>=j
- //printf("goal[%d]=%d\n",i,j);
- }
- dfs(0);
- for(i=1;i<=n;i++){
- if(a[i]=='#')printf("0 ");
- else printf("%d ",ans[i]);
- }
- puts("");
- }
- }
K. Running Threads
考虑费用流建图:
- $S$向每条记录连边,流量$[0,1]$,费用$0$,表示一组的开始。
- 记录$i$向记录$j$连边,流量$[0,1]$,费用$0$,表示一组延续。
- 记录向线程连边,流量$[0,1]$,费用$w$,表示一组的结束。
- 每条线程向$T$连边,流量$[0,1]$,费用$0$,表示只接受最多一组记录。
- 每条记录拆点,中间连边,流量$[1,1]$,费用$0$。
那么两问分别对应这个有上下界的网络的最小/最大费用可行流。
- #include<cstdio>
- typedef long long ll;
- const int N=1000,M=1000000;
- const ll inf=1LL<<60;
- int Case,n,m,i,j,a[N],b[N];
- ll sum;
- int u[M],v[M],c[M],co[M],nxt[M],t,S,T,SS,TT,l,r,q[M];
- int g[N],f[N];
- bool vis[N];
- ll d[N];
- int in[N];
- int tmp;ll ans;
- inline void add(int x,int y,int l,int r,int zo){
- r-=l;
- in[x]-=l;
- in[y]+=l;
- if(!r)return;
- u[++t]=x;v[t]=y;c[t]=r;co[t]=zo;nxt[t]=g[x];g[x]=t;
- u[++t]=y;v[t]=x;c[t]=0;co[t]=-zo;nxt[t]=g[y];g[y]=t;
- }
- bool spfa(){
- int x,i;
- for(i=1;i<=TT;i++)d[i]=inf,vis[i]=0;
- d[SS]=0;
- vis[SS]=1;
- l=r=M>>1;
- q[l]=SS;
- while(l<=r){
- int x=q[l++];
- if(x==TT)continue;
- for(i=g[x];i;i=nxt[i])if(c[i]&&co[i]+d[x]<d[v[i]]){
- d[v[i]]=co[i]+d[x];f[v[i]]=i;
- if(!vis[v[i]]){
- vis[v[i]]=1;
- if(d[v[i]]<d[q[l]])q[--l]=v[i];else q[++r]=v[i];
- }
- }
- vis[x]=0;
- }
- return d[TT]<inf;
- }
- int main(){
- freopen("threads.in","r",stdin);
- scanf("%d",&Case);
- while(Case--){
- scanf("%d%d",&n,&m);
- sum=0;
- for(i=1;i<=m;i++)scanf("%d",&a[i]),sum+=a[i];
- for(i=1;i<=n;i++)scanf("%d",&b[i]);
- S=n*2+m+1;
- T=S+1;
- SS=T+1;
- TT=SS+1;
- for(t=i=1;i<=TT;i++)g[i]=in[i]=0;
- add(T,S,0,N,0);
- for(i=1;i<=n;i++){
- add(i,i+n,1,1,0);
- add(S,i,0,1,0);
- for(j=1;j<=m;j++)if(b[i]<=a[j])add(i+n,j+n*2,0,1,-b[i]);
- for(j=i+1;j<=n;j++)if(b[i]<b[j])add(i+n,j,0,1,0);
- }
- for(i=1;i<=m;i++)add(i+n*2,T,0,1,0);
- for(i=1;i<=TT;i++){
- if(in[i]>0)add(SS,i,0,in[i],0);
- if(in[i]<0)add(i,TT,0,-in[i],0);
- }
- ans=0;
- while(spfa()){
- for(tmp=N,i=TT;i!=SS;i=u[f[i]])if(tmp>c[f[i]])tmp=c[f[i]];
- for(ans+=d[i=TT]*tmp;i!=SS;i=u[f[i]])c[f[i]]-=tmp,c[f[i]^1]+=tmp;
- }
- ans*=-1;
- printf("%lld ",sum-ans);
- S=n*2+m+1;
- T=S+1;
- SS=T+1;
- TT=SS+1;
- for(t=i=1;i<=TT;i++)g[i]=in[i]=0;
- add(T,S,0,N,0);
- for(i=1;i<=n;i++){
- add(i,i+n,1,1,0);
- add(S,i,0,1,0);
- for(j=1;j<=m;j++)if(b[i]<=a[j])add(i+n,j+n*2,0,1,b[i]);
- for(j=i+1;j<=n;j++)if(b[i]<b[j])add(i+n,j,0,1,0);
- }
- for(i=1;i<=m;i++)add(i+n*2,T,0,1,0);
- for(i=1;i<=TT;i++){
- if(in[i]>0)add(SS,i,0,in[i],0);
- if(in[i]<0)add(i,TT,0,-in[i],0);
- }
- ans=0;
- while(spfa()){
- for(tmp=N,i=TT;i!=SS;i=u[f[i]])if(tmp>c[f[i]])tmp=c[f[i]];
- for(ans+=d[i=TT]*tmp;i!=SS;i=u[f[i]])c[f[i]]-=tmp,c[f[i]^1]+=tmp;
- }
- printf("%lld\n",sum-ans);
- }
- }
- /*
- 3
- 6 3
- 8 12 7
- 5
- 3
- 7
- 3
- 4
- 9
- 3 3
- 1000000000 999999999 999999998
- 1
- 10
- 1000
- 5 3
- 9 5 8
- 9
- 3
- 6
- 5
- 8
- */
L. Knights
设$f[i][a][b][c][d]$表示从上到下考虑前$i$行,最后$4$行的骑士跳跃方向分别为$a,b,c,d$的方案数。
需要根据可行性将$a$压缩到$3$,$b,c$压缩到$5$,$d$压缩到$7$才能通过。
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- const int N=550,P=1000000007;
- int cnt,id[3][5][5][7],p[N][4],g[N][9];
- int Case,n,m,w,i,j,k,a[N],f[N][N],ans;
- char ch[N];
- int v[N][N];
- int dx[9]={0,2,2,1,1,-1,-1,-2,-2};
- int dy[9]={0,-1,1,-2,2,-2,2,-1,1};
- inline void up(int&a,int b){
- a=a+b<P?a+b:a+b-P;
- }
- void init(){
- for(int A=0;A<3;A++)for(int B=0;B<5;B++)for(int C=0;C<5;C++)for(int D=0;D<7;D++){
- int now=cnt++;
- id[A][B][C][D]=now;
- p[now][0]=A;
- p[now][1]=B;
- p[now][2]=C;
- p[now][3]=D;
- }
- for(int A=0;A<3;A++)for(int B=0;B<5;B++)for(int C=0;C<5;C++)for(int D=0;D<7;D++){
- int now=id[A][B][C][D];
- for(int i=1;i<9;i++){
- int nA=B,nB=C,nC=D,nD=i;
- if(nA>=3)nA=0;
- if(nB>=5)nB=0;
- if(nC>=5)nC=0;
- if(nD>=7)nD=0;
- g[now][i]=id[nA][nB][nC][nD];
- }
- }
- }
- int main(){
- freopen("knights.in","r",stdin);
- init();
- scanf("%d",&Case);
- while(Case--){
- scanf("%d%d",&n,&m);
- for(i=1;i<=n;i++){
- scanf("%s",ch+1);
- for(j=1;j<=m;j++){
- if(ch[j]=='*')a[i]=j;
- v[i][j]=ch[j]!='.';
- }
- }
- for(i=0;i<=n;i++)for(j=0;j<cnt;j++)f[i][j]=0;
- f[0][0]=1;
- for(i=0;i<n;i++)for(j=0;j<cnt;j++)if(f[i][j]){
- w=f[i][j];
- int A=p[j][0],B=p[j][1],C=p[j][2],D=p[j][3];
- if(A)v[i-3+dx[A]][a[i-3]+dy[A]]++;
- if(B)v[i-2+dx[B]][a[i-2]+dy[B]]++;
- if(C)v[i-1+dx[C]][a[i-1]+dy[C]]++;
- if(D)v[i+dx[D]][a[i]+dy[D]]++;
- for(k=1;k<9;k++){
- int x=i+1+dx[k],y=a[i+1]+dy[k];
- if(x>=1&&x<=n&&y>=1&&y<=m&&!v[x][y])
- up(f[i+1][g[j][k]],w);
- }
- if(A)v[i-3+dx[A]][a[i-3]+dy[A]]--;
- if(B)v[i-2+dx[B]][a[i-2]+dy[B]]--;
- if(C)v[i-1+dx[C]][a[i-1]+dy[C]]--;
- if(D)v[i+dx[D]][a[i]+dy[D]]--;
- }
- ans=0;
- for(j=0;j<cnt;j++)up(ans,f[n][j]);
- printf("%d\n",ans);
- }
- }
M. Winning Cells
问题等价于两个$K-Nim$游戏,那么只要$A\bmod (K+1)\neq B\bmod (K+1)$则先手必胜。
反过来考虑计算必败态的个数,那么考虑$1$到$N$每个数模$K+1$的值,可以将这些数分成贡献不同的两组分别计算。
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- typedef long long ll;
- const int N=100010;
- int T,n,k;long long ans;
- inline int fun(int a,int b){return a|b;}
- int main(){
- freopen("chess.in","r",stdin);
- scanf("%d",&T);
- while(T--){
- scanf("%d%d",&n,&k);k++;
- int m=n/k*k;
- int base=n/k;
- //[0..k-1] base
- //[1..n%k] base+1
- ans=1LL*n*n;
- int A=n%k,B=k-A;
- ans-=1LL*base*base*B;
- base++;
- ans-=1LL*base*base*A;
- printf("%lld\n",ans);
- }
- }
2017 ACM Jordanian Collegiate Programming Contest的更多相关文章
- 2017 ACM Arabella Collegiate Programming Contest(solved 11/13)
省选考前单挑做点ACM练练细节还是很不错的嘛- 福利:http://codeforces.com/gym/101350 先来放上惨不忍睹的virtual participate成绩(中间跑去食堂吃饭于 ...
- 容斥 或者 单调栈 hihocoder #1476 : 矩形计数 和 G. Snake Rana 2017 ACM Arabella Collegiate Programming Contest
先说一个简单的题目(题目大意自己看去,反正中文):hihocoder上的:http://hihocoder.com/problemset/problem/1476 然后因为这个n和m的矩阵范围是100 ...
- 脑洞 博弈 E. Competitive Seagulls 2017 ACM Arabella Collegiate Programming Contest
题目链接:http://codeforces.com/gym/101350/problem/E 题目大意:给你一个长度为n的方格,方格上面都被染色成了白色.每次染色都是选择白色的,假设目前选择的这块白 ...
- 2017 ACM Amman Collegiate Programming Contest 题解
[题目链接] A - Watching TV 模拟.统计一下哪个数字最多即可. #include <bits/stdc++.h> using namespace std; const in ...
- 2017 ACM Amman Collegiate Programming Contest
A - Watching TV /* 题意:求出出现次数最多的数字 */ #include <cstdio> #include <algorithm> #include < ...
- 2017 ACM Arabella Collegiate Programming Contest(solved 9/13, complex 12/13)
A.Sherlock Bones 题意: 给出长度为n的01串,问f(i,j)=f(j,k),(i<j<k)的i,j,k取值种数.其中f(i,j)表示[i,j]内1的个数, 且s[j]必须 ...
- 2017 ACM Arabella Collegiate Programming Contest div2的题,部分题目写个题解
F. Monkeying Around 维护点在多少个线段上 http://codeforces.com/gym/101350/problem/F 题意:有m个笑话,每个笑话的区间是[L, R], ...
- ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. Poor Ramzi -dp+记忆化搜索
ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. ...
- ACM International Collegiate Programming Contest World Finals 2014
ACM International Collegiate Programming Contest World Finals 2014 A - Baggage 题目描述:有\(2n\)个字符摆在编号为\ ...
随机推荐
- tensorflow 语音识别报错
cuDnn由7.1版本改为7.4.2.24版本,成功
- Mock6 moco框架中如何加入header
新建一个 startupWithHeader.json,这次在request里面添加了headers属性 [ { "description": "这是一个带header的 ...
- MySQL_表锁_lock tables tableName read
pre.环境准备 1.建立两个表S,T,并插入一些数据 --创建表S create table S(d int) engine=innodb; ); --创建表T create table T(c i ...
- maven 构建参数和命令
mvn常用参数 mvn -e 显示详细错误 mvn -U 强制更新snapshot类型的插件或依赖库(否则maven一天只会更新一次snapshot依赖) mvn -o 运行offline模式,不联网 ...
- BOM:浏览器对象模型之浏览器剖析入门
BOM简介 BOM与DOM的关系 BOM对象包含的内容 重新认识浏览器 一.分裂的BOM和被收服的DOM BOM定义:是browser object model的缩写,简称浏览器对象模型. 主要处理浏 ...
- ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(记忆化搜索)
https://nanti.jisuanke.com/t/31454 题意 两个人玩游戏,最初数字为m,有n轮,每轮三个操作给出a b c,a>0表示可以让当前数字加上a,b>0表示可以让 ...
- [物理学与PDEs]第2章第1节 理想流体力学方程组 1.1 预备知识
1. 理想流体: 指忽略粘性及热传导的流体. 2. 流体的状态 (运动状态及热力学状态) 的描述 (1) 速度向量 $\bbu=(u_1,u_2,u_3)$: 流体微元的宏观运动速度. (2) ...
- SSRF漏洞挖掘经验
SSRF概述 SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞.一般情况下,SSRF攻击的目标是从外网无法访问 ...
- PageUtil.java分页工具类
package com.chabansheng.util; /** * 分页工具类 * @author Administrator * */ public class PageUtil { /** * ...
- AC的故事大结局山寨版(下)
AC的故事大结局山寨版(下) TimeLimit:2000MS MemoryLimit:128MB 64-bit integer IO format:%lld Problem Descripti ...