第二次被ceilks艹翻的无奈啊。。

Villages and Tribes

模拟不解释

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 100009
using namespace std;
char a[N];
int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int T;cin>>T;while (T--){cin>>a;int last=-1,pos=-1,ans1=0,ans2=0,n=strlen(a);for (int i=0;i<n;i++){if (a[i]=='A'&&last==0){ans1+=i-pos-1;pos=i;}if (a[i]=='B'&&last==1){ans2+=i-pos-1;pos=i;}if (a[i]=='A'){ans1++;last=0;pos=i;}if (a[i]=='B'){ans2++;last=1;pos=i;}}cout<<ans1<<" "<<ans2<<endl;}return 0;
}

Chef goes Left Right Left

判断对区间就好。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define inf 2e9
using namespace std;
int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int T;cin>>T;while (T--){int n,x;cin>>n>>x;int last=0,flag=1,now,Min=-inf,Max=inf;for (int i=1;i<=n;i++){cin>>now;if (i>1&&now>last&&last>x|now<last&&last<x) flag=0;if (now>=Max||now<=Min) flag=0;if (now>x) Max=min(Max,now);if (now<x) Min=max(Min,now);last=now;}if (now!=x) flag=0;cout<<(flag?"YES":"NO")<<endl;}return 0;
}

Periodic Palindrome Construction

除了特判就没了。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
using namespace std;
int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int T;cin>>T;while (T--){int x,y;cin>>x>>y;if (y<=2) cout<<"impossible"<<endl;else{if (y&1){for (int t=1;t<=x/y;t++)for (int i=1;i<=y;i++) cout<<(i&1?"a":"b");}else{for (int t=1;t<=x/y;t++){for (int i=1;i<=y/2;i++) cout<<(i&1?"a":"b");for (int i=y/2+1;i<=y;i++) cout<<(i&1?"b":"a");}}cout<<endl;}}return 0;
}

Chef Hates Palindromes

字符集大小A≥3A\geq3的,显然形如abcabcabcabc的串是没有长度大于2的回文子串的,然后等于2的发现小范围打表暴力,大范围都可以表示为abaabbabaabb的循环串。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
using namespace std;
const char a[6]={'a','b','a','a','b','b'};
const char b[3]={'a','b','c'};
int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int T;cin>>T;while (T--){int n,A;cin>>n>>A;if (A==1){cout<<n<<" ";for (int i=1;i<=n;i++) cout<<'a';cout<<endl;}if (A==2){if (n==1) cout<<"1 a\n";else if (n==2) cout<<"1 ab\n";else if (n==3) cout<<"2 aab\n";else if (n==4) cout<<"2 aabb\n";else if (n==5) cout<<"3 aaaba\n";else if (n==6) cout<<"3 aaabab\n";else if (n==7) cout<<"3 aaababb\n";else if (n==8) cout<<"3 aaababbb\n";else{cout<<"4 ";for (int i=0;i<n;i++) cout<<a[i%6];cout<<endl;}}if (A>=3){cout<<"1 ";for (int i=0;i<n;i++) cout<<b[i%3];cout<<endl;}}return 0;
}

Chef and Subarray Queries

无脑线段树维护就好了。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define root 1,1,n
#define mid (l+r>>1)
#define lc cur<<1
#define rc lc|1
#define lson lc,l,mid
#define rson rc,mid+1,r
#define N 500009
using namespace std;
int n,q,L,R;
struct node
{ll ans1,ans2;int l_len1,r_len1,l_len2,r_len2,Max;void change(int x){Max=x;if (x<L) l_len1=r_len1=ans1=1;else l_len1=r_len1=ans1=0;if (x<=R) l_len2=r_len2=ans2=1;else l_len2=r_len2=ans2=0;}friend node operator +(const node &lhs,const node &rhs){node ret;ret.Max=max(lhs.Max,rhs.Max);if (lhs.Max<L) ret.l_len1=lhs.l_len1+rhs.l_len1;else ret.l_len1=lhs.l_len1;if (rhs.Max<L) ret.r_len1=rhs.r_len1+lhs.r_len1;else ret.r_len1=rhs.r_len1;if (lhs.Max<=R) ret.l_len2=lhs.l_len2+rhs.l_len2;else ret.l_len2=lhs.l_len2;if (rhs.Max<=R) ret.r_len2=rhs.r_len2+lhs.r_len2;else ret.r_len2=rhs.r_len2;ret.ans1=(ll)lhs.r_len1*rhs.l_len1+lhs.ans1+rhs.ans1;ret.ans2=(ll)lhs.r_len2*rhs.l_len2+lhs.ans2+rhs.ans2;return ret;}
}tr[N<<2];
void build(int cur,int l,int r)
{if (l==r){tr[cur].change(0);return;}build(lson);build(rson);tr[cur]=tr[lc]+tr[rc];
}
void change(int cur,int l,int r,int x,int y)
{if (l==r){tr[cur].change(y);return;}if (x<=mid) change(lson,x,y);else change(rson,x,y);tr[cur]=tr[lc]+tr[rc];
}
node qry(int cur,int l,int r,int L,int R)
{if (L<=l&&R>=r) return tr[cur];if (R<=mid) return qry(lson,L,R);elseif (L>mid) return qry(rson,L,R);else return qry(lson,L,R)+qry(rson,L,R);
}
int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>q>>L>>R;build(root);while (q--){int op,x,y;cin>>op>>x>>y;if (op==1) change(root,x,y);else{node Ans=qry(root,x,y);printf("%lld\n",Ans.ans2-Ans.ans1);}}return 0;
}

Product on the segment by modulo

似乎是个套路?
原来以为只是CRT然后卡卡常数,后来发现似乎我过不了(不知道又没有过的啊)。
发现有除法就得计算逆元或者类似的东西,很烦,考虑只有乘法。
如果可以离线,显然可以分治轻松过,然而这题强制在线,所以我们将分治每一层[l,r][l,r]区间中到mid=l+r2mid=\frac{l+r}{2}的前缀后缀积算出来,显然就可以在询问时小常数O(logn)O(logn)查询出所在区间并计算了。(似乎是uoj上某位大佬写的)

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define pii pair<int,int>
#define mid (l+r>>1)
#define N 2000009
using namespace std;
int n,m,mod,q,last,x,y,L,R,a[N],b[N][21];
void solve(int l,int r,int k)
{if (l==r){b[l][k]=a[l]%mod;return;}for (int i=mid;i>=l;i--)b[i][k]=(i==mid?(a[i]%mod):((ll)b[i+1][k]*a[i]%mod));for (int i=mid+1;i<=r;i++)b[i][k]=(i==mid+1?(a[i]%mod):((ll)b[i-1][k]*a[i]%mod));solve(l,mid,k+1);solve(mid+1,r,k+1);
}
int get(int l,int r)
{if (l==r) return a[l]%mod;for (int i=m>>1,j=0;;i>>=1,j++)if (!(l&i)&&(r&i)){//cout<<i<<endl;return (ll)b[l][j]*b[r][j]%mod;}
}
int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int T;cin>>T;while (T--){cin>>n>>mod>>q;for (int i=0;i<n;i++) cin>>a[i];m=1;while (m<n) m<<=1;solve(0,m-1,0);L=R=last=0;cin>>y;for (int i=0;i<q;i++){if (i%64==0){x=y;cin>>y;L=(x+last)%n;R=(y+last)%n;}else{L=(L+last)%n;R=(R+last)%n;}if (L>R) swap(L,R);last=(get(L,R)+1)%mod;//cout<<L<<R<<last-1<<endl;}cout<<last<<endl;}return 0;
}

Lovers Gift

正着做似乎挺难,考虑倒着做。
相当于原来有一堆有银行的城市,逐渐减少到零。
我们发现相当于求跟这个点不在同一个连通块中的点的第二大点权值。
每次少一个银行相当于将一堆连通块合并(假装把每个银行当成特殊的一种连通块)。每个连通块维护前两大权值,然后塞入set中,每次合并连通块,删去set中少掉的两个值。每次在set中最多查询4个就必然可以查询到。
总复杂度大概O((n+m)(logn+α(n)))O((n+m)(logn+\alpha(n)))

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 100009
using namespace std;
int n,m,first[N],number,vis[N],fa[N],pd[N],Max[N][2];
struct edge
{int to,next;void add(int x,int y){to=y,next=first[x],first[x]=number;}
}e[N<<1];
set<int,greater<int> > st;
set<int,greater<int> > ::iterator it;
struct mdy
{int op,x,Ans;
}q[N];
int read()
{int x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;int s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return s*x;
}
void dfs(int x,int y)
{fa[x]=y;if (x>Max[y][0]) Max[y][1]=Max[y][0],Max[y][0]=x;else if (x>Max[y][1]) Max[y][1]=x;vis[x]=1;for (int i=first[x];i;i=e[i].next)if (!vis[e[i].to]&&!pd[e[i].to]) dfs(e[i].to,y);
}
int find(int x)
{return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int x,int y)
{x=find(x),y=find(y);if (Max[x][0]>Max[y][0]){fa[y]=x;if (Max[x][1]>Max[y][0]){st.erase(Max[y][0]);st.erase(Max[y][1]);}else{st.erase(Max[x][1]);st.erase(Max[y][1]);Max[x][1]=Max[y][0];}}else{fa[x]=y;if (Max[y][1]>Max[x][0]){st.erase(Max[x][0]);st.erase(Max[x][1]);}else{st.erase(Max[x][1]);st.erase(Max[y][1]);Max[y][1]=Max[x][0];}}
}
int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int T;cin>>T;while (T--){cin>>n>>m;for (int i=1;i<=n;i++) pd[i]=vis[i]=first[i]=0,fa[i]=i;number=0;for (int i=1;i<n;i++){int x,y;cin>>x>>y;e[++number].add(x,y),e[++number].add(y,x);}for (int i=1;i<=m;i++){cin>>q[i].op>>q[i].x;if (q[i].op==1) pd[q[i].x]++;}memset(Max,0,sizeof(Max));for (int i=1;i<=n;i++)if (!vis[i]&&!pd[i]) dfs(i,i);else if (pd[i]) Max[i][0]=i;st.clear();for (int i=1;i<=n;i++)if (find(i)==i){if (Max[i][0]) st.insert(Max[i][0]);if (Max[i][1]) st.insert(Max[i][1]);}for (int i=m;i;i--){if (q[i].op==1){if (--pd[q[i].x]) continue;for (int j=first[q[i].x];j;j=e[j].next)if (!pd[e[j].to]) merge(q[i].x,e[j].to);}else{int flag=1;it=st.begin();for (int j=1;j<=2;j++){while (it!=st.end()&&(find((*it))==find(q[i].x)&&(!pd[*it]))) it++;if (it==st.end()){flag=0;break;}if (j==1) it++;}if (flag) q[i].Ans=*it;else q[i].Ans=-1;}}for (int i=1;i<=m;i++)if (q[i].op==2) cout<<q[i].Ans<<endl;}return 0;
}

Polynomials

这题我调试出来我自己都不信了啊。
相当于求nn个(小于)三次函数的类似半平面交的东西。
考虑将nn个函数归并处理,据外校大佬说似乎可以证明最终区间数小于等于O(n)O(n)个。(大概最多3倍?)
然后就是考虑两个三次函数求交点了。
这次比赛的结果告诉我们,中国人发明的公式虽然看起来很菜,但实际上是最好用的(盛金公式)(雾)。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define mid (l+r>>1)
#define N 100003
#define inf 2e5
#define eps 1e-9
using namespace std;
ll n,q,Ans[N];
struct jiao
{double x,y,z;jiao(double x=0.0,double y=0.0,double z=0.0):x(x),y(y),z(z){}
};
struct func
{ll a0,a1,a2,a3;double f(double x){return (double)a0+a1*x+a2*x*x+a3*x*x*x;}
}a[N];
struct node
{ll beg,pos;node(ll beg=0,ll pos=0):beg(beg),pos(pos){}
};
struct line
{vector <node> q;
};
jiao get_jiao(ll pos1,ll pos2)
{if (a[pos1].a3==a[pos2].a3){if (a[pos1].a2==a[pos2].a2){if (a[pos1].a1==a[pos2].a1) return jiao(inf+1,inf+1,inf+1);return jiao((double)(a[pos2].a0-a[pos1].a0)/(a[pos1].a1-a[pos2].a1),inf+1,inf+1);}else{ll A=a[pos1].a2-a[pos2].a2;ll B=a[pos1].a1-a[pos2].a1;ll C=a[pos1].a0-a[pos2].a0;double delta=B*B-4.0*A*C;if (fabs(delta)<eps) return jiao(-B/2.0/(double)A,inf+1,inf+1);if (delta<0) return jiao(inf+1,inf+1,inf+1);return jiao((-B-sqrt(delta))/2.0/A,(-B+sqrt(delta))/2.0/A,inf+1);}}else{ll aa=a[pos1].a3-a[pos2].a3;ll bb=a[pos1].a2-a[pos2].a2;ll cc=a[pos1].a1-a[pos2].a1;ll dd=a[pos1].a0-a[pos2].a0;double A=bb*bb-3*aa*cc;double B=bb*cc-9*aa*dd;double C=cc*cc-3*bb*dd;if (fabs(A)<eps&&fabs(B)<eps) return jiao(-B/3.0/(double)A,inf+1,inf+1);double delta=B*B-4*A*C;if (fabs(delta)<eps) return jiao(-bb/aa+B/A,-B/2.0/A,inf+1);if (delta>0){double Y1=A*bb+3.0*aa*(-B+sqrt(delta))/2.0;double Y2=A*bb+3.0*aa*(-B-sqrt(delta))/2.0;if (Y1>0) Y1=pow(Y1,1.0/3.0);else Y1=-pow(fabs(Y1),1.0/3.0);if (Y2>0) Y2=pow(Y2,1.0/3.0);else Y2=-pow(fabs(Y2),1.0/3.0);double X1=(-bb-Y1-Y2)/3.0/aa;return jiao(X1,inf+1,inf+1);}double T=(2.0*A*bb-3.0*aa*B)/(2.0*pow(A,1.5));double th=acos(T);double X1=(-bb-2.0*sqrt(A)*cos(th/3.0))/3.0/aa;double X2=(-bb+sqrt(A)*(cos(th/3.0)+sqrt(3.0)*sin(th/3.0)))/3.0/aa;double X3=(-bb+sqrt(A)*(cos(th/3.0)-sqrt(3.0)*sin(th/3.0)))/3.0/aa;return jiao(X1,X2,X3);}
}
line solve(ll l,ll r)
{if (l==r){line ret;ret.q.clear();ret.q.push_back(node(0,l));return ret;}line ret;ret.q.clear();line L=solve(l,mid);line R=solve(mid+1,r);ll now=0,now_pos=0;for (ll i=0;i<(ll)L.q.size();){if (now_pos>((i==(ll)L.q.size()-1)?inf:L.q[i+1].beg-1)) i++;if (i==(ll)L.q.size()) break;ll rpos1=(i==(ll)L.q.size()-1)?inf:L.q[i+1].beg-1;while (((now<(R.q.size()-1))?(R.q[now+1].beg-1):(inf))<now_pos) now++;ll lpos2=R.q[now].beg,rpos2=(now==(ll)R.q.size()-1)?inf:(R.q[now+1].beg-1);ll lpos=now_pos,rpos=min(rpos1,rpos2);//if (l==1&&r==5) cout<<now_pos<<" "<<lpos2<<" "<<rpos2<<endl;jiao ji=get_jiao(L.q[i].pos,R.q[now].pos);vector<double> Q;if (ji.x<inf&&ji.x>=lpos&&ji.x<=rpos) Q.push_back(ji.x);if (ji.y<inf&&ji.y>=lpos&&ji.y<=rpos) Q.push_back(ji.y);if (ji.z<inf&&ji.z>=lpos&&ji.z<=rpos) Q.push_back(ji.z);Q.push_back(lpos),Q.push_back(rpos);sort(Q.begin(),Q.end());for (ll j=1;j<Q.size();j++){ll pos=Q[j-1];if (pos<Q[j-1]) pos++;if (a[L.q[i].pos].f(pos)<a[R.q[now].pos].f(pos))ret.q.push_back(node(pos,L.q[i].pos));elseif (a[L.q[i].pos].f(pos)>a[R.q[now].pos].f(pos))ret.q.push_back(node(pos,R.q[now].pos));elseif (a[L.q[i].pos].f(pos+0.5)<a[R.q[now].pos].f(pos+0.5))ret.q.push_back(node(pos,L.q[i].pos));elseret.q.push_back(node(pos,R.q[now].pos));if (ret.q.size()>=2)if (ret.q.back().pos==(ret.q[ret.q.size()-2].pos)) ret.q.pop_back();}now_pos=rpos+1;}return ret;
}
int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);ll T;cin>>T;while (T--){cin>>n;for (ll i=1;i<=n;i++)cin>>a[i].a0>>a[i].a1>>a[i].a2>>a[i].a3;line ret=solve(1,n);//puts("-----------------------");cin>>q;ll now=0;for (ll i=0;i<N;i++){while (now<(ret.q.size()-1)&&ret.q[now+1].beg<=i) now++;Ans[i]=ret.q[now].pos;}while (q--){ll x;cin>>x;cout<<(ll)a[Ans[x]].f(x)<<endl;}}return 0;
}

Day Schedule

我只想知道为什么缩写跟题目名字毫无关系??(BINOMSUM)
据梁大大刚开赛时说,dls这道题只会40分。(合理猜测:dls:这TM40分不是随便拿;某大佬:woc??!!dls只会40!!好难!!)然后一天后,梁大大又跟我说他会了。(woc,梁大大果然无敌了啊)
这题调试出来那可能我更不信了。。
好吧来理一理思路。
首先我们发现这题的A(娱乐活动数??)和K(天数)是给定的。
所以对于每一天,不同的D,它的方案数我们可以表示成一个多项式。
先忽略第一个小时的特点,我们发现活动可以分为两种:即进行娱乐或者进行娱乐后吃饭。
根据这个我们可以很轻松地写出这个多项式:

f(D)=∑i=0⌊n2⌋Cin−iDiAn−i,(n=k−1)

f(D)=\sum_{i=0}^{\lfloor\frac{n}{2}\rfloor}C_{n-i}^{i}D^{i}A^{n-i},(n=k-1)
通过这个公式我们发现我们似乎一分都拿不到(wtf??)
所以前面的公式屁用没有。。。
(下文高能预警)
考虑将这个多项式 f(D)f(D)表示为上升幂形式。
也就是说:

f(D)=∑i=0⌊n2⌋ai∏j=1i(D+j)

f(D)=\sum_{i=0}^{\lfloor\frac{n}{2}\rfloor}a_i\prod_{j=1}^{i}(D+j)
然后带入答案式子:

Ans=∑T=0Tmax−1CLD+Tf(D+T)=∑T=0Tmax−1(D+T)!L!(D+T−L)!∑i=0⌊n2⌋ai∏j=1i(D+T+j)=∑T=0Tmax−1(D+T)!L!(D+T−L)!∑i=0⌊n2⌋ai(D+T+i)!(D+T)!=∑T=0Tmax−11L!∑i=0⌊n2⌋ai(D+T+i)!(D+T−L)!=∑T=0Tmax−11L!∑i=0⌊n2⌋aiCL+iD+T+i(L+i)!=∑i=0⌊n2⌋ai(L+i)!L!∑T=0Tmax−1CL+iD+T+i=∑i=0⌊n2⌋ai(L+i)!L!(CL+i+1D+Tmax+i−CL+i+1D+i)

Ans=\sum_{T=0}^{T_{max}-1}C_{D+T}^{L}f(D+T)\\=\sum_{T=0}^{T_{max}-1}\frac{(D+T)!}{L!(D+T-L)!}\sum_{i=0}^{\lfloor\frac{n}{2}\rfloor}a_i\prod_{j=1}^{i}(D+T+j)\\=\sum_{T=0}^{T_{max}-1}\frac{(D+T)!}{L!(D+T-L)!}\sum_{i=0}^{\lfloor\frac{n}{2}\rfloor}a_i\frac{(D+T+i)!}{(D+T)!}\\=\sum_{T=0}^{T_{max}-1}\frac{1}{L!}\sum_{i=0}^{\lfloor\frac{n}{2}\rfloor}a_i\frac{(D+T+i)!}{(D+T-L)!}\\=\sum_{T=0}^{T_{max}-1}\frac{1}{L!}\sum_{i=0}^{\lfloor\frac{n}{2}\rfloor}a_iC_{D+T+i}^{L+i}(L+i)!\\=\sum_{i=0}^{\lfloor\frac{n}{2}\rfloor}a_i\frac{(L+i)!}{L!}\sum_{T=0}^{T_{max}-1}C_{D+T+i}^{L+i}\\=\sum_{i=0}^{\lfloor\frac{n}{2}\rfloor}a_i\frac{(L+i)!}{L!}(C_{D+T_{max}+i}^{L+i+1}-C_{D+i}^{L+i+1})
通过预处理阶乘和阶乘逆元,我们可以做到 O(K)O(K)的时间回答每一次询问,所以我们只需要考虑 aia_i系数数组如何求得。
设 m=⌊n2⌋m=\lfloor\frac{n}{2}\rfloor
考虑

f(D)=∑i=0mai∏j=1i(D+j)

f(D)=\sum_{i=0}^{m}a_i\prod_{j=1}^{i}(D+j)
取 D=−1,−2,……,−m−1D=-1,-2,……,-m-1
发现

f(−1)=a0

f(-1)=a_0

f(−2)=a0−a1

f(-2)=a_0-a_1

f(−m−1)=∑i=0mbi(−1)im!(m−i)!=m!∑i=0mbi(−1)i(m−i)!

f(-m-1)=\sum_{i=0}^{m}b_i(-1)^i\frac{m!}{(m-i)!}\\=m!\sum_{i=0}^{m}\frac{b_i(-1)^i}{(m-i)!}
考虑构造多项式

F(x)=∑i=0mf(−i−1)i!xi

F(x)=\sum_{i=0}^{m}\frac{f(-i-1)}{i!}x^i
我们发现 F=A×BF=A\times B
其中

A(x)=∑i=0maixi

A(x)=\sum_{i=0}^{m}a_ix^i

B(x)=∑i=0m(−x)ii!

B(x)=\sum_{i=0}^{m}\frac{(-x)^i}{i!}
而F的系数可以通过矩阵快速幂求得,于是a就可以在b这个多项式求逆后得到。(然而由于模数输入,我就写了(拉的模板)3个NTT质数NTT后CRT得到答案)
然而还可以更优秀(wanglichao1121发现的),我们发现 B(x)B(x)的逆元显然就是

B′(x)=∑i=0mxii!

B'(x)=\sum_{i=0}^{m}\frac{x^i}{i!}(可以考虑 exe^x的泰勒展开)
至此,这道题就完美完成了。。
(中间的乘法实际上可以分治乘并不需要NTT然而我分治乘的常数实在太大了)

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 200009
#define M 12000009
using namespace std;
ll a[M],inv[M],f[N],b[N],inv_b[N],p[N];
ll n,k,A,mod,q,m;
ll L,D,T;
struct matrix
{ll a[2][2];friend matrix operator *(const matrix &A,const matrix &B){matrix ret;for (int i=0;i<2;i++)for (int j=0;j<2;j++){ret.a[i][j]=0;for (int k=0;k<2;k++) ret.a[i][j]=(ret.a[i][j]+A.a[i][k]*B.a[k][j]%mod)%mod;}return ret;}
};
#define K 3
const ll mm[K]={1004535809,998244353,104857601};
#define G 3
ll qpow(ll x,ll k,ll P)
{ll ret=1;while (k){if (k&1) ret=1LL*ret*x%P;k>>=1;x=1LL*x*x%P;}return ret;
}
struct _NTT
{ll w[2][N],P;void init(ll _P){P=_P;}void pre(ll n){w[0][0]=w[0][n]=w[1][0]=w[1][n]=1;ll GG=qpow(G,(P-1)/n,P);for (ll i=1;i<n;i++) w[0][i]=w[0][i-1]*GG%P;for (ll i=1;i<n;i++) w[1][i]=w[0][n-i];}void change(ll *y,ll len){for (ll i=1,j=len/2;i<len-1;++i){if (i<j) swap(y[i],y[j]);ll k=len/2;while (j>=k){j-=k;k/=2;}j+=k;}}void NTT(ll *a,ll n,ll v){for (ll i=0,j=0;i<n;i++){if (i>j) swap(a[i],a[j]);for (ll l=n>>1;(j^=l)<l;l>>=1);}for (ll i=2;i<=n;i<<=1)for (ll j=0;j<n;j+=i)for (ll l=0;l<i>>1;l++){ll t=a[j+l+(i>>1)]*w[v][(n/i)*l]%P;a[j+l+(i>>1)]=(a[j+l]-t+P)%P;a[j+l]=(a[j+l]+t)%P;}if (v)for (ll i=0,t=qpow(n,P-2,P);i<n;i++) a[i]=a[i]*t%P;}void mul(ll A[],ll B[],ll len){pre(len);NTT(A,len,0);NTT(B,len,0);for (ll i=0;i<len;++i) A[i]=1LL*A[i]*B[i]%P;NTT(A,len,1);}
}ntt[K];
ll tmp[N][K],t1[N],t2[N];
ll r[K][K];
ll CRT(ll a[])
{ll x[K];for (ll i=0;i<K;++i){x[i]=a[i];for (ll j=0;j<i;++j){ll t=(x[i]-x[j])%mm[i];if (t<0) t+=mm[i];x[i]=1LL*t*r[j][i]%mm[i];}}ll mul=1,ret=x[0]%mod;for (ll i=1;i<K;++i){mul=1LL*mul*mm[i-1]%mod;ret+=1LL*x[i]*mul%mod;if (ret>=mod) ret-=mod;}return ret;
}
void mul(ll A[],ll B[],ll len,ll C[])
{for (ll id=0;id<K;++id){for (ll i=0;i<len;++i){t1[i]=A[i];t2[i]=B[i];}ntt[id].mul(t1,t2,len);for (ll i=0;i<len;++i)tmp[i][id]=t1[i];}for (ll i=0;i<len;++i)C[i]=CRT(tmp[i]);
}
void init()
{for (ll i=0;i<K;++i)for (ll j=0;j<i;++j)r[j][i]=qpow(mm[j],mm[i]-2,mm[i]);for (ll i=0;i<K;++i)ntt[i].init(mm[i]);
}
ll ksm(ll x,ll y)
{ll ret=1;for (;y;y>>=1,x=x*x%mod)if (y&1) ret=ret*x%mod;return ret;
}
ll miao[N],lych[N],aa[N],bb[N],cc[N],dd[N],ee[N],ff[N],gg[N];
/*void mul(ll a[],ll b[],ll m,ll c[])
{if (m==1){c[0]=(ll)a[0]*b[0]%mod;return;}for (int i=0;i<m;i++){if (i<(m>>1)) bb[i]=a[i],dd[i]=b[i];else aa[i-(m>>1)]=a[i],cc[i-(m>>1)]=b[i];}mul(aa,cc,m>>1,ee);mul(bb,dd,m>>1,ff);for (int i=0;i<(m>>1);i++)aa[i]=(aa[i]+bb[i])%mod,cc[i]=(cc[i]+dd[i])%mod;mul(aa,cc,m>>1,gg);for (int i=0;i<(m<<1);i++) c[i]=0;for (int i=0;i<m;i++)c[i+m]=(c[i+m]+ee[i])%mod;for (int i=0;i<m;i++)c[i+(m>>1)]=(c[i+(m>>1)]+gg[i]-ee[i]-ff[i]+mod+mod)%mod;for (int i=0;i<m;i++)c[i]=(c[i]+ff[i])%mod;
}*/
ll c(ll n,ll m)
{if (n<m) return 0;return (ll)a[n]*inv[m]%mod*inv[n-m]%mod;
}
ll get_f(ll x)
{matrix zy,ret;ret.a[1][0]=ret.a[1][1]=ret.a[0][0]=0,ret.a[0][1]=1;zy.a[0][0]=zy.a[1][0]=A;zy.a[0][1]=x,zy.a[1][1]=0;for (ll i=n;i;i>>=1,zy=zy*zy)if (i&1) ret=ret*zy;return (ret.a[0][0]+ret.a[0][1])%mod;
}
void get_inv(ll a[],ll b[],ll m)
{if (m==1){b[0]=ksm(a[0],mod-2);return;}get_inv(a,miao,m>>1);for (int i=(m>>1);i<m;i++) miao[i]=0;for (int i=0;i<m;i++) aa[i]=a[i];for (int i=m;i<(m<<1);i++) aa[i]=0;mul(aa,miao,m<<1,lych);lych[0]=(mod+2-lych[0])%mod;for (int i=1;i<m;i++) lych[i]=mod-lych[i];for (int i=m;i<(m<<1);i++) lych[i]=0;mul(miao,lych,m<<1,b);for (int i=m;i<(m<<1);i++) b[i]=0;
}
int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);init();cin>>k>>A>>mod>>q;n=k-1;m=1;while (m<=n/2) m<<=1;a[0]=1;for (ll i=1;i<M;i++) a[i]=a[i-1]*i%mod;inv[0]=inv[1]=1;for (ll i=2;i<M;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;for (ll i=2;i<M;i++) inv[i]=inv[i]*inv[i-1]%mod;for (ll i=0;i<m;i++)f[i]=get_f(mod-i-1)*inv[i]%mod;for (ll i=0;i<m;i++)b[i]=inv[i];get_inv(b,inv_b,m);ll wlc[N];memset(wlc,0,sizeof(wlc));mul(inv_b,b,m<<1,wlc);mul(f,inv_b,m<<1,p);for (int i=0;i<=n/2;i++)if (i&1) p[i]=mod-p[i];while (q--){cin>>L>>D>>T;ll Ans=0;for (ll i=0;i<=n/2;i++){ll ret=p[i]*a[i+L]%mod*inv[L]%mod;ret=ret*(c(D+i+T,i+L+1)-c(D+i,i+L+1)+mod)%mod;Ans=(Ans+ret)%mod;}Ans=(Ans%mod+mod)%mod;cout<<Ans<<endl;}return 0;
}

Chef and Intersection Line

这道题第一个难点在于判断线段相交,这个是计算几何的问题,然而可以全部存为int判断。
然后先来考虑一种比较直接的想法。
每一时刻都尽量选择最优(权值最大)的点加入答案,这样只需要写一个线段相交就可以。我们发现这样的得分大概在55分左右(一开始有60分好像)。
然后根据我们的答案可以画出(写个程序吧孩子)大致路线图。发现它在没有什么限制的条件时,选择的点往往太过于远了。(简单来说,太浪了)
所以我们将当前点排序时要加入离上一个点的曼哈顿距离作为第二个参数。这样大概调一下参数,再枚举起点,大概可以在中间的某一个时刻获得100分。(后来91、2分这样子)
这样似乎还是不够优秀,因为它往往还是太浪了。。
所以(以下为梁大大想出)我们思考枚举中间点的位置(比如说第25个点实在哪),然后向两边宽搜。这样似乎又多了点分。。
似乎剩下加的优化就只有对于第二种数据生成方式,按照固定的路线跑了。(似乎又多了一点分)
最后这样大概就94分了。(梁大大似乎参数比我强很多啊,日本小哥和ceilks可能还有高论啊,我果然还是最菜啊)

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define M 509
#define N 59
#define zero(x) ((x)==0)
#define inf 1e9
using namespace std;
int n,m,a[M][N][N],pd[N][N],Max,ID,Time,type;
const double alpha[4]={0.4,2.0,0.95,1.0};
const int MAX_SIZE[2][2]={{-1,100},{50,50}};
int MID;
struct point
{int x,y;point(int x=0,int y=0):x(x),y(y){}friend point operator +(const point &A,const point &B){return point(A.x+B.x,A.y+B.y);}friend point operator -(const point &A,const point &B){return point(A.x-B.x,A.y-B.y);}friend point operator *(const point &A,const int &B){return point(A.x*B,A.y*B);}
};
int xmult(point p1,point p2,point p0)
{return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int dmult(point p1,point p2,point p0)
{return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}
int dots_inline(point p1,point p2,point p3)
{return zero(xmult(p1,p2,p3));
}
int dot_online_in(point p,point l1,point l2)
{return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<=0&&(l1.y-p.y)*(l2.y-p.y)<=0;
}
int same_side(point p1,point p2,point l1,point l2)
{return xmult(l1,p1,l2)*xmult(l1,p2,l2)>0;
}
int parallel(point u1,point u2,point v1,point v2)
{return zero((u1.x-u2.x)*(v1.y-v2.y)-(v1.x-v2.x)*(u1.y-u2.y));
}
int intersect_in(point u1,point u2,point v1,point v2)
{int x=xmult(u1,v2,v1)*xmult(u2,v2,v1);int y=xmult(v1,u2,u1)*xmult(v2,u2,u1);if (x>0||y>0) return 0;if (x<0&&y<0) return 1;return dot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);
}
struct node
{int x,y,z,val;node(int x=0,int y=0,int z=0,int val=0):x(x),y(y),z(z),val(val){}bool operator <(const node &rhs) const{return val>rhs.val||(val==rhs.val&&(x<<6|y)<(rhs.x<<6|rhs.y));}
};
vector<point> Ans,Final;
double get(node x)
{return x.val-(double)alpha[ID]*(4.0-Time/125.0)*(abs(x.x-Ans.back().x)+abs(x.y-Ans.back().y));
}
bool cmp(node x,node y)
{return get(x)>get(y);
}
double Get(node x)
{return x.val-(double)alpha[ID]*(abs(x.x-Ans.back().x)+abs(x.y-Ans.back().y));
}
bool Cmp(node x,node y)
{return Get(x)>Get(y);
}
double get1(node x)
{return x.val-(double)alpha[ID+2]*(abs(x.x-Ans[Time-1].x)+abs(x.y-Ans[Time-1].y));
}
bool cmp1(node x,node y)
{return get1(x)>get1(y);
}
vector<node> p[M];
bool check(int x,int y)
{if (pd[x][y]) return 0;if ((int)Ans.size()<=1) return 1;int ed=Ans.size()-1;if (dots_inline(Ans[ed-1],Ans[ed],point(x,y)))if (!(Ans[ed].x<Ans[ed-1].x&&x<Ans[ed].x||x>Ans[ed].x&&Ans[ed].x>Ans[ed-1].x)&&!(Ans[ed].y<Ans[ed-1].y&&y<Ans[ed].y||y>Ans[ed].y&&Ans[ed].y>Ans[ed-1].y)) return 0;for (int i=1;i<ed;i++)if (intersect_in(Ans[i-1],Ans[i],Ans[ed],point(x,y))) return 0;return 1;
}
bool check_inv(int x,int y)
{if (pd[x][y]) return 0;if ((int)Ans.size()<=1) return 1;int beg=0;if (dots_inline(Ans[beg+1],Ans[beg],point(x,y)))if (!(Ans[beg].x<Ans[beg+1].x&&x<Ans[beg].x||x>Ans[beg].x&&Ans[beg].x>Ans[beg+1].x)&&!(Ans[beg].y<Ans[beg+1].y&&y<Ans[beg].y||y>Ans[beg].y&&Ans[beg].y>Ans[beg+1].y)) return 0;for (int i=beg+2;i<(int)Ans.size();i++)if (intersect_in(Ans[i-1],Ans[i],Ans[beg],point(x,y))) return 0;return 1;
}
bool is_ok(int x,int y)
{if (pd[x][y]) return 0;if (x>n||x<1||y>n||y<1) return 0;return 1;
}
node q[M];
int bfs(int k,int x,int y)
{int head=1,tail=1,ret=a[k][x][y];q[tail]=node(x,y,k,a[k][x][y]);bool flag=0;while (head<=tail){if (head==1){int t_now=k-1;Time=k;node cho=node(0,0,0,-inf);int num=0;for (int i=0;i<(int)p[t_now].size();i++){node now=p[t_now][i];if (check_inv(now.x,now.y)){if (cmp1(now,cho)) cho=now;if ((++num)>3) break;}}if (num){ret+=cho.val;Ans.insert(Ans.begin(),point(cho.x,cho.y));pd[cho.x][cho.y]=1;q[++tail]=cho;}t_now=k+1;cho=node(0,0,0,-inf);num=0;for (int i=0;i<(int)p[t_now].size();i++){node now=p[t_now][i];if (check(now.x,now.y)){if (cmp1(now,cho)) cho=now;if ((++num)>3) break;}}if (num){ret+=cho.val;Ans.push_back(point(cho.x,cho.y));pd[cho.x][cho.y]=1;q[++tail]=cho;}}else{int t_now=(q[head].z<k)?q[head].z-1:q[head].z+1;if (t_now==0){flag=1;head++;continue;}if (t_now>m){head++;continue;}Time=k;node cho=node(0,0,0,-inf);int num=0;for (int i=0;i<(int)p[t_now].size();i++){node now=p[t_now][i];if ((t_now>k)?check(now.x,now.y):check_inv(now.x,now.y)){if (cmp1(now,cho)) cho=now;if ((++num)>3) break;}}if (num){ret+=cho.val;if (t_now<k) Ans.insert(Ans.begin(),point(cho.x,cho.y));else Ans.push_back(point(cho.x,cho.y));pd[cho.x][cho.y]=1;q[++tail]=cho;}}head++;}if (!flag) return 0;return ret;
}
int main()
{int ttt=clock();ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m;if (m==50) ID=0;else ID=1;for (int i=1;i<=m;i++){p[i].clear();for (int j=1;j<=n;j++)for (int k=1;k<=n;k++){cin>>a[i][j][k];p[i].push_back(node(j,k,i,a[i][j][k]));}}int sss=0;sss+=a[1][1][1]+a[1][1][2]+a[1][2][1];sss+=a[1][1][n]+a[1][1][n-1]+a[1][2][n];sss+=a[1][n][1]+a[1][n-1][1]+a[1][n][2];sss+=a[1][n][n]+a[1][n-1][n]+a[1][n][n-1];if (sss>=500) type=1;else type=0;int ret=0;for (int i=1;i<=m;i++) sort(p[i].begin(),p[i].end());if (m==50&&type==0)for (int t=0;t<n*n;t++){memset(pd,0,sizeof(pd));Ans.clear();Ans.push_back(point(p[1][t].x,p[1][t].y));ret=p[1][t].val;pd[p[1][t].x][p[1][t].y]=1;for (int i=2;i<=m;i++){bool flag=0;for (int j=0;j<(int)p[i].size();j++){node now=p[i][j];if (check(now.x,now.y)){flag=1;ret+=now.val;Ans.push_back(point(now.x,now.y));pd[now.x][now.y]=1;break;}}if (!flag) break;}if (ret>Max){Max=ret;Final.clear();for (int i=0;i<(int)Ans.size();i++)Final.push_back(Ans[i]);}}if (m==50&&type==0) cerr<<Max<<endl;for (int t=0;t<MAX_SIZE[ID][type];t++){memset(pd,0,sizeof(pd));Ans.clear();Ans.push_back(point(p[1][t].x,p[1][t].y));pd[p[1][t].x][p[1][t].y]=1;ret=p[1][t].val;for (int i=1;i<2500;i++) assert(p[1][i-1].val>=p[1][i].val);for (int i=2;i<=m;i++){Time=i;sort(p[i].begin(),p[i].end(),Cmp);bool flag=0;for (int j=0;j<(int)p[i].size();j++){node now=p[i][j];if (check(now.x,now.y)){flag=1;ret+=now.val;Ans.push_back(point(now.x,now.y));pd[now.x][now.y]=1;break;}}if (!flag) break;}if (ret>Max){Max=ret;Final.clear();for (int i=0;i<(int)Ans.size();i++)Final.push_back(Ans[i]);}}if (m!=50||type==1) cerr<<Max<<endl;for (int i=1;i<=m;i++) sort(p[i].begin(),p[i].end());if (m==50&&type==0){for (MID=22;MID<=28;MID++)for (int t=0;t<n*n;t++)if (p[MID][t].val>3){int i=p[MID][t].x,j=p[MID][t].y;memset(pd,0,sizeof(pd));Ans.clear();Ans.push_back(point(i,j));pd[i][j]=1;ret=bfs(MID,i,j);if (ret>Max){Max=ret;Final.clear();for (int k=0;k<(int)Ans.size();k++)Final.push_back(Ans[k]);}}cerr<<Max<<endl;}if (m==500){for (MID=44;MID<=56;MID++)for (int t=0;t<n*n;t++)if (p[MID][t].val>35){int i=p[MID][t].x,j=p[MID][t].y;memset(pd,0,sizeof(pd));Ans.clear();Ans.push_back(point(i,j));pd[i][j]=1;ret=bfs(MID,i,j);if (ret>Max){Max=ret;Final.clear();for (int k=0;k<(int)Ans.size();k++)Final.push_back(Ans[k]);}}cerr<<Max<<endl;}if (m==500&&type==1){Ans.clear();ret=Time=0;for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(j,10-i+1)),ret+=a[++Time][j][10-i+1];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(j,i+40)),ret+=a[++Time][j][i+40];}for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(50-(i-j),40+i)),ret+=a[++Time][50-(i-j)][40+i];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(50-j+1,11-i)),ret+=a[++Time][50-j+1][11-i];}for (int i=40;i>=16;i--)Ans.push_back(point(i,1)),ret+=a[++Time][i][1];for (int i=16;i<=25;i++)for (int j=41-i;j<=i+10;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];for (int i=26;i<=35;i++)for (int j=i-10;j<=61-i;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];if (ret>Max){Max=ret;Final.clear();for (int k=0;k<(int)Ans.size();k++)Final.push_back(Ans[k]);}cerr<<Max<<endl;}if (m==500&&type==1){for (int i=1;i<=m;i++)for (int j=1;j<=n;j++)for (int k=1;k*2<=n;k++)swap(a[i][j][k],a[i][j][n-k+1]);Ans.clear();ret=Time=0;for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(j,10-i+1)),ret+=a[++Time][j][10-i+1];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(j,i+40)),ret+=a[++Time][j][i+40];}for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(50-(i-j),40+i)),ret+=a[++Time][50-(i-j)][40+i];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(50-j+1,11-i)),ret+=a[++Time][50-j+1][11-i];}for (int i=40;i>=16;i--)Ans.push_back(point(i,1)),ret+=a[++Time][i][1];for (int i=16;i<=25;i++)for (int j=41-i;j<=i+10;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];for (int i=26;i<=35;i++)for (int j=i-10;j<=61-i;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];if (ret>Max){Max=ret;Final.clear();for (int k=0;k<(int)Ans.size();k++)Final.push_back(point(Ans[k].x,n-Ans[k].y+1));}cerr<<Max<<endl;for (int i=1;i<=m;i++)for (int j=1;j<=n;j++)for (int k=1;k*2<=n;k++)swap(a[i][j][k],a[i][j][n-k+1]);}if (m==500&&type==1){for (int i=1;i<=m;i++)for (int j=1;j*2<=n;j++)for (int k=1;k<=n;k++)swap(a[i][j][k],a[i][n-j+1][k]);Ans.clear();ret=Time=0;for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(j,10-i+1)),ret+=a[++Time][j][10-i+1];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(j,i+40)),ret+=a[++Time][j][i+40];}for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(50-(i-j),40+i)),ret+=a[++Time][50-(i-j)][40+i];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(50-j+1,11-i)),ret+=a[++Time][50-j+1][11-i];}for (int i=40;i>=16;i--)Ans.push_back(point(i,1)),ret+=a[++Time][i][1];for (int i=16;i<=25;i++)for (int j=41-i;j<=i+10;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];for (int i=26;i<=35;i++)for (int j=i-10;j<=61-i;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];if (ret>Max){Max=ret;Final.clear();for (int k=0;k<(int)Ans.size();k++)Final.push_back(point(n-Ans[k].x+1,Ans[k].y));}cerr<<Max<<endl;for (int i=1;i<=m;i++)for (int j=1;j*2<=n;j++)for (int k=1;k<=n;k++)swap(a[i][j][k],a[i][n-j+1][k]);}if (m==500&&type==1){for (int i=1;i<=m;i++)for (int j=1;j*2<=n;j++)for (int k=1;k<=n;k++)swap(a[i][j][k],a[i][n-j+1][k]);for (int i=1;i<=m;i++)for (int j=1;j<=n;j++)for (int k=1;k*2<=n;k++)swap(a[i][j][k],a[i][j][n-k+1]);Ans.clear();ret=Time=0;for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(j,10-i+1)),ret+=a[++Time][j][10-i+1];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(j,i+40)),ret+=a[++Time][j][i+40];}for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(50-(i-j),40+i)),ret+=a[++Time][50-(i-j)][40+i];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(50-j+1,11-i)),ret+=a[++Time][50-j+1][11-i];}for (int i=40;i>=16;i--)Ans.push_back(point(i,1)),ret+=a[++Time][i][1];for (int i=16;i<=25;i++)for (int j=41-i;j<=i+10;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];for (int i=26;i<=35;i++)for (int j=i-10;j<=61-i;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];if (ret>Max){Max=ret;Final.clear();for (int k=0;k<(int)Ans.size();k++)Final.push_back(point(n-Ans[k].x+1,n-Ans[k].y+1));}cerr<<Max<<endl;for (int i=1;i<=m;i++)for (int j=1;j*2<=n;j++)for (int k=1;k<=n;k++)swap(a[i][j][k],a[i][n-j+1][k]);for (int i=1;i<=m;i++)for (int j=1;j<=n;j++)for (int k=1;k*2<=n;k++)swap(a[i][j][k],a[i][j][n-k+1]);}if (m==500&&type==1){Ans.clear();ret=Time=0;for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(j,10-i+1)),ret+=a[++Time][j][10-i+1];}for (int i=11;i<=40;i++) Ans.push_back(point(1,i)),ret+=a[++Time][1][i];for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(j,i+40)),ret+=a[++Time][j][i+40];}for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(50-(i-j),40+i)),ret+=a[++Time][50-(i-j)][40+i];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(50-j+1,11-i)),ret+=a[++Time][50-j+1][11-i];}for (int i=40;i>=16;i--)Ans.push_back(point(i,1)),ret+=a[++Time][i][1];for (int i=16;i<=25;i++)for (int j=41-i;j<=i+10;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];for (int i=26;i<=35;i++)for (int j=i-10;j<=61-i;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];if (ret>Max){Max=ret;Final.clear();for (int k=0;k<(int)Ans.size();k++)Final.push_back(Ans[k]);}cerr<<Max<<endl;}if (m==500&&type==1){for (int i=1;i<=m;i++)for (int j=1;j<=n;j++)for (int k=1;k*2<=n;k++)swap(a[i][j][k],a[i][j][n-k+1]);Ans.clear();ret=Time=0;for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(j,10-i+1)),ret+=a[++Time][j][10-i+1];}for (int i=11;i<=40;i++) Ans.push_back(point(1,i)),ret+=a[++Time][1][i];for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(j,i+40)),ret+=a[++Time][j][i+40];}for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(50-(i-j),40+i)),ret+=a[++Time][50-(i-j)][40+i];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(50-j+1,11-i)),ret+=a[++Time][50-j+1][11-i];}for (int i=40;i>=16;i--)Ans.push_back(point(i,1)),ret+=a[++Time][i][1];for (int i=16;i<=25;i++)for (int j=41-i;j<=i+10;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];for (int i=26;i<=35;i++)for (int j=i-10;j<=61-i;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];if (ret>Max){Max=ret;Final.clear();for (int k=0;k<(int)Ans.size();k++)Final.push_back(point(Ans[k].x,n-Ans[k].y+1));}cerr<<Max<<endl;for (int i=1;i<=m;i++)for (int j=1;j<=n;j++)for (int k=1;k*2<=n;k++)swap(a[i][j][k],a[i][j][n-k+1]);}if (m==500&&type==1){for (int i=1;i<=m;i++)for (int j=1;j*2<=n;j++)for (int k=1;k<=n;k++)swap(a[i][j][k],a[i][n-j+1][k]);Ans.clear();ret=Time=0;for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(j,10-i+1)),ret+=a[++Time][j][10-i+1];}for (int i=11;i<=40;i++) Ans.push_back(point(1,i)),ret+=a[++Time][1][i];for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(j,i+40)),ret+=a[++Time][j][i+40];}for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(50-(i-j),40+i)),ret+=a[++Time][50-(i-j)][40+i];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(50-j+1,11-i)),ret+=a[++Time][50-j+1][11-i];}for (int i=40;i>=16;i--)Ans.push_back(point(i,1)),ret+=a[++Time][i][1];for (int i=16;i<=25;i++)for (int j=41-i;j<=i+10;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];for (int i=26;i<=35;i++)for (int j=i-10;j<=61-i;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];if (ret>Max){Max=ret;Final.clear();for (int k=0;k<(int)Ans.size();k++)Final.push_back(point(n-Ans[k].x+1,Ans[k].y));}cerr<<Max<<endl;for (int i=1;i<=m;i++)for (int j=1;j*2<=n;j++)for (int k=1;k<=n;k++)swap(a[i][j][k],a[i][n-j+1][k]);}if (m==500&&type==1){for (int i=1;i<=m;i++)for (int j=1;j*2<=n;j++)for (int k=1;k<=n;k++)swap(a[i][j][k],a[i][n-j+1][k]);for (int i=1;i<=m;i++)for (int j=1;j<=n;j++)for (int k=1;k*2<=n;k++)swap(a[i][j][k],a[i][j][n-k+1]);Ans.clear();ret=Time=0;for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(j,10-i+1)),ret+=a[++Time][j][10-i+1];}for (int i=11;i<=40;i++) Ans.push_back(point(1,i)),ret+=a[++Time][1][i];for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(j,i+40)),ret+=a[++Time][j][i+40];}for (int i=10;i;i--){for (int j=1;j<=i;j++)Ans.push_back(point(50-(i-j),40+i)),ret+=a[++Time][50-(i-j)][40+i];}for (int i=1;i<=10;i++){for (int j=1;j<=i;j++)Ans.push_back(point(50-j+1,11-i)),ret+=a[++Time][50-j+1][11-i];}for (int i=40;i>=16;i--)Ans.push_back(point(i,1)),ret+=a[++Time][i][1];for (int i=16;i<=25;i++)for (int j=41-i;j<=i+10;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];for (int i=26;i<=35;i++)for (int j=i-10;j<=61-i;j++)Ans.push_back(point(i,j)),ret+=a[++Time][i][j];if (ret>Max){Max=ret;Final.clear();for (int k=0;k<(int)Ans.size();k++)Final.push_back(point(n-Ans[k].x+1,n-Ans[k].y+1));}cerr<<Max<<endl;for (int i=1;i<=m;i++)for (int j=1;j*2<=n;j++)for (int k=1;k<=n;k++)swap(a[i][j][k],a[i][n-j+1][k]);for (int i=1;i<=m;i++)for (int j=1;j<=n;j++)for (int k=1;k*2<=n;k++)swap(a[i][j][k],a[i][j][n-k+1]);}for (int i=0;i<(int)Final.size();i++)cout<<Final[i].x<<" "<<Final[i].y<<endl;if ((int)Final.size()<m) cout<<-1<<" "<<-1<<endl;cerr<<clock()-ttt<<endl;return 0;
}

附图:


codechef November Challenge 2017解题报告相关推荐

  1. codechef October Challenge 2017解题报告

    第二次打challenge..果然还是拿不到钱(艹不过大佬)啊. A Balanced Contest 模拟就好. #include <bits/stdc++.h> #define gc ...

  2. CFCC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries

    https://www.codechef.com/DEC17/problems/CHEFEXQ 题意: 位置i的数改为k 询问区间[1,i]内有多少个前缀的异或和为k 分块 sum[i][j] 表示第 ...

  3. CodeChef June Challenge 2017

    好气啊,本来以为比赛时间还有很多,结果回家养病两天回到学校怎么比赛就结束了(雾),大约是小高考弄错了时间? 挑3道有意思的写写题解吧. Cloning 题目大意:给一个序列,每次询问两个等长区间,问区 ...

  4. CodeChef March Challenge 2017 题解

    CC XENTASK 由于要交替选,所以要不第一个人选位置为奇数的数,第二个人选位置为偶数的数,要不第一个人选位置为偶数的数,第二个人选位置为奇数的数.取最小值即可. #include <cst ...

  5. [CodeChef FEB15]Payton numbers(CUSTPRIM)解题报告

    题目 https://www.codechef.com/problems/CUSTPRIM (翻译来自洪华敦) 定义三元组的乘法 def multiply((a1,b1,c1), (a2,b2,c2) ...

  6. 【网易2017春招】赶去公司 解题报告

    [网易2017春招]赶去公司 解题报告 标签(空格分隔): 牛客网 题目地址:https://www.nowcoder.com/questionTerminal/5c7657015d3d49369c4 ...

  7. LOJ#6072. 「2017 山东一轮集训 Day5」苹果树 解题报告

    LOJ#6072. 「2017 山东一轮集训 Day5」苹果树 解题报告 好苹果会组成连通块,整棵树的权值为 ∑ i = 1 n c i [ c i ≥ 0 ] [ s i z n u m ( c i ...

  8. LOJ#6103. 「2017 山东二轮集训 Day2」第一题 解题报告

    LOJ#6103. 「2017 山东二轮集训 Day2」第一题 解题报告 前置知识:闭区间上的连续函数的零点存在性定理: 我们定义这样的函数: 定义域为 [ l , r ] ∩ Z [l,r]\cap ...

  9. 解题报告(十八)数论题目泛做(Codeforces 难度:2000 ~ 3000 + )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

最新文章

  1. Windows SharePoint Services 3.0 应用程序模板
  2. 数据库中INFORMATION_SCHEMA的说明及使用
  3. python基础实例-Python基础之字符串常见操作经典实例详解
  4. 虚拟机增强工具的安装
  5. vc中调用其他应用程序的方法(函数) winexec,shellexecute ,createprocess
  6. unity 批量导入模型工具_零基础的Unity图形学笔记3:使用多模型UV与优化模型导出...
  7. 论文遇到的格式问题和修正方式
  8. 1227讲解(递归deng)
  9. java导入日期处理,java实现Excel表格的导入日期变成数字的问题
  10. python延时队列_超简便Python任务队列:huey
  11. linux 下搭建postfix服务器
  12. 创建MyOffice项目
  13. 刑法中关于计算机犯罪的定义,界定计算机犯罪概念的原则
  14. 行业下行,丧失亮点的OPPO慢人一步
  15. 调用谷歌Chrome浏览器打不开网页崩溃了
  16. 【新年快乐】2022年跨年钟声即将敲响,2021终将成为历史
  17. linux 禁用usb驱动程序,如何使用musb_hdrc Linux驱动程序断开特定的USB设备?
  18. 标准成本还是实际成本 成本核算标准选择
  19. 无锁编程与分布式编程那个更适合多核CPU?
  20. iOS12 Xcode10正式版问题汇总以及新特性(持续更新中....)

热门文章

  1. linux游戏object怎么玩,用Object Detection玩第一人称射击游戏
  2. 华为p40pro换鸿蒙,华为p40Pro、p40怎么升级鸿蒙系统
  3. ratelimit+redis+lua对接口限流
  4. linux怎么打开rpm文件怎么打开,RPM格式文件怎么打开
  5. 简易扩音机设计1——麦克风篇
  6. 透视Linux内核 神奇的BPF二
  7. 根据美光内存颗粒上的编码查询对应型号
  8. 微信小程序获取用户信息“授权失败”场景的处理
  9. 如何减少页面的重绘和回流(14)
  10. 凡科php项目模块,如何创建一个DouPHP新模块