1.滞空(jump/1s/64M)
#include<bits/stdc++.h> using namespace std; typedef long long LL; const LL mod = 998244353; inline void rd(LL &x) { x=0;int f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} } LL n,m,x[2],y[2],g,ans; LL qpow(LL a) { LL res=1,k=mod-2; while(k) { if(k&1)res=res*a%mod; a=a*a%mod; k>>=1; } return res; } LL _2 = qpow(2); void down(LL x,LL h){x%=mod;h%=mod; ans += (x*x*m%mod)*qpow(4*h); ans%=mod;} void up(LL x,LL h) {x%=mod;h%=mod; ans += (m*h%mod) + ( (x*x*m%mod) *qpow(4*h) )%mod; ans%=mod;} void pi_4(LL x){x%=mod; ans += (m*x%mod)*_2; ans%=mod;} void solve() { scanf("%lld%lld%lld",&n,&m,&g); rd(x[1]); rd(y[1]); for(int i=2;i<=n;i++) { rd(x[i&1]); rd(y[i&1]); if(y[i&1]>y[!(i&1)]) up(x[i&1]-x[!(i&1)],y[i&1]-y[!(i&1)]); if(y[i&1]<y[!(i&1)]) down(x[i&1]-x[!(i&1)],y[!(i&1)]-y[i&1]); if(y[i&1]==y[!(i&1)]) pi_4(x[i&1]-x[!(i&1)]); } printf("%lldJ",ans*g%mod); } int main() { freopen("jump.in","r",stdin); freopen("jump.out","w",stdout); solve(); fclose(stdin); fclose(stdout); return 0; }
2.放爆竹(bomb/1s/64M)
题解
but......暴力出奇迹,拿70pt
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstdlib> #include<string> #include<cstring> #include<queue> using namespace std; inline int read() { int ans=0; char last=' ',ch=getchar(); while(ch<'0'||ch>'9') last=ch,ch=getchar(); while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar(); if(last=='-') ans=-ans; return ans; } const int maxn=20010; int n,ans=0,ans1,l1,l2; string ss; bool flag=0; struct node{ string s; int len; }chuan[maxn]; bool cmp(node x,node y) { if(x.len ==y.len ) return x.s >y.s ; else return x.len >y.len ; } int gcd(int x,int y) { return y==0?x:gcd(y,x%y); } int lcm(int x,int y){ return x*y/(gcd(x,y)); } int work(int x,int y) { int res=0,answ=0; string s1=chuan[x].s,s2=chuan[y].s ; int len1=chuan[x].len ,len2=chuan[y].len ; int len=lcm(len1,len2); for(int i=0;i<len;i++){ if(s1[i%len1]!=s2[i%len2] ){ res=max(res,answ); answ=0; break; } else{ answ++; res=max(res,answ); } } return res; } int main() { freopen("bomb.in","r",stdin); freopen("bomb.out","w",stdout); n=read(); for(int i=1;i<=n;i++) { cin>>ss; chuan[i].s =ss; chuan[i].len =ss.size() ; } sort(chuan+1,chuan+n+1,cmp); for(int i=1;i<=n;i++){ if(flag) break; for(int j=i+1;j<=n;j++) { l1=chuan[i].len ,l2=chuan[j].len; if(lcm(l1,l2)<ans){ flag=1; break; } ans1=work(i,j); if(ans1>ans) ans=ans1; } } printf("%d ",ans); return 0; }
正解代码:
#include <bits/stdc++.h> using std::max; using std::strlen; const int N=20010,Mlen=510,Node=N*Mlen*2; int n,len[N],ans; char s[N][Mlen]; struct Trie{ int son[Node][2],node,app[Node],dep[Node],f[Node]; void init() { son[0][0]=son[0][1]=0; app[0]=dep[0]=0; } int newnode(int d){ ++node; son[node][0]=son[node][1]=0; dep[node]=d; app[node]=0; return node; } void insert(char *s,int len,int t) { int p=0,add=0; while (t) { for (int i=0;i<len && add<=1000;++i) { int &x=son[p][s[i]-'0'],pp=p; p=x?x:x=newnode(dep[p]+1); f[p]=pp; app[p]++; add++; } t--; } } int FindAns() { int ans=0; for (int i=1;i<=node;++i) if (app[i]>=2) { ans=max(ans,dep[i]); } // for (int i=1;i<=node;++i) if (app[i]>=2 && ans==dep[i]) { // int p=i; // while (p) { // putchar((p==son[f[p]][1])+'0'); // p=f[p]; // } // putchar(' '); // break; // } return ans; } }tr; void Init() { scanf("%d",&n); for (int i=1;i<=n;++i) { scanf("%s",s[i]); len[i]=strlen(s[i]); } } void Solve() { tr.init(); for (int i=1;i<=n;++i) { tr.insert(s[i],len[i],(1000-1)/len[i]+1); } printf("%d ",tr.FindAns()); } int main() { freopen("bomb.in","r",stdin); freopen("bomb.out","w",stdout); Init(); Solve(); fclose(stdin); fclose(stdout); return 0; }
3.pyy整队(queue,1s,128M)
代码
#include<bits/stdc++.h> using namespace std; typedef long long LL; #define mid ((l+r)>>1) const int N=2e5+10,inf=0x3f3f3f3f; int n,m,rt; int L[N<<1], R[N<<1], v[N<<1]; int a[N], b[N], pos[N], nxt[N], pre[N], cs, cnt; void build(int &i,int l,int r) { i = ++cs; if(l<r) build(L[i],l,mid), build(R[i],mid+1,r), v[i] = min( v[L[i]] , v[R[i]] ); else v[i] = pos[l]; } void alter(int i,int l,int r,int p) { if(l<r) { if(p<=mid) alter(L[i],l,mid,p); else alter(R[i],mid+1,r,p); v[i] = min(v[L[i]],v[R[i]]); } else v[i] = ++cnt; } inline int query(int i,int l,int r,int k) { while(l<r) { if(v[L[i]]<=k) i = L[i], r = mid; else i = R[i], l = mid + 1; } return l; } void solve() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]), b[i] = a[i]; sort(b+1,b+1+n); for(int i=1;i<=n;i++)//离散化a初始排列 { a[i] = lower_bound(b+1,b+1+n,a[i]) - b; nxt[a[i-1]] = a[i]; pre[a[i]] = a[i-1]; pos[a[i]] = i; } build(rt,1,n); cnt = n; int last = a[n];//last队尾 while(m--) { static char s[8]; static int x,t; scanf("%s%d",s,&x); t = lower_bound(b+1,b+1+n,x) - b; if(s[0]=='A') { if(!pre[t]) printf("-1 "); else printf("%d ",b[ query(rt,1,n,pos[pre[t]]) ]);//查询小于等于pos[pre_t]的最小值的人 } else { if(last==t)continue; alter(rt,1,n,t);//单点修改第t人pos pos[t] = cnt; nxt[pre[t]] = nxt[t]; pre[nxt[t]] = pre[t];//当前的前后驱修改 pre[t] = last; nxt[last] = t; last = t; } } sort(pos+1,pos+1+n); int tail = 1, ans = inf; for(int i=1;i<=n && tail<n;i++) { while(pos[tail] - pos[i] + 1<n && tail<=n) tail++; if(tail>n || pos[tail] - pos[i] + 1>n) tail--; ans = min(ans,i-1 + n-tail);//左右区间剩下的 } printf("%d ",ans); } int main() { freopen("queue.in","r",stdin); freopen("queue.out","w",stdout); solve(); fclose(stdin); fclose(stdout); return 0; }