The 2023 ICPC Asia Hangzhou Regional Contest (The 2nd Universal Cup. Stage 22: Hangzhou)

题解:

https://files.cnblogs.com/files/clrs97/2023hangzhou_tutorials-2-22.pdf

 

Code:

A. Submissions

#include <bits/stdc++.h>
using namespace std;
using Submission = tuple<string, char, int, string>;
using Score = pair<int, int>;
Score operator+(const Score &s0, const Score &s1) {
  return Score(s0.first + s1.first, s0.second + s1.second);
}
Score operator-(const Score &s0, const Score &s1) {
  return Score(s0.first - s1.first, s0.second - s1.second);
}
int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  int T;
  cin >> T;
  for (int ti = 0; ti < T; ti += 1) {
    int n = 0, m;
    cin >> m;
    vector<Submission> submissions(m);
    unordered_map<string, int> mp;
    vector<string> names;
    vector<array<vector<pair<int, bool>>, 26>> tp;
    for (auto &[c, p, t, s] : submissions) {
      cin >> c >> p >> t >> s;
      if (not mp.count(c)) {
        mp[c] = n++;
        names.push_back(c);
        tp.emplace_back();
      }
      tp[mp[c]][p - 'A'].emplace_back(t, s == "accepted");
    }
    auto print = [&](string s) {
      cout << count(s.begin(), s.end(), '1') << "\n";
      for (int i = 0; i < n; i += 1) {
        if (s[i] == '1') { cout << names[i] << " "; }
      }
      cout << "\n";
    };
    auto score = [&](const vector<pair<int, bool>> &vp) -> Score {
      int p = 0;
      for (auto [t, s] : vp) {
        if (s) { return Score(1, -t - p); }
        p += 20;
      }
      return Score(0, 0);
    };
    vector<Score> s(n), bs(n), ws(n);
    for (int i = 0; i < n; i += 1) {
      for (int j = 0; j < 26; j += 1) { s[i] = s[i] + score(tp[i][j]); }
      bs[i] = ws[i] = s[i];
      for (int j = 0; j < 26; j += 1) {
        auto vp = tp[i][j];
        if (not vp.empty()) { vp[0].second = true; }
        bs[i] = max(bs[i], s[i] - score(tp[i][j]) + score(vp));
      }
      for (int j = 0; j < 26; j += 1) {
        auto vp = tp[i][j];
        for (auto &[t, s] : vp) {
          if (s) {
            s = false;
            break;
          }
        }
        ws[i] = min(ws[i], s[i] - score(tp[i][j]) + score(vp));
      }
    }
    int k = n - count(s.begin(), s.end(), Score(0, 0));
    int r = min((k + 9) / 10, 35);
    auto ss = s;
    sort(ss.begin(), ss.end());
    string ans(n, '0');
    if (k == 0) { ss.emplace_back(1, numeric_limits<int>::min()); }
    for (int i = 0; i < n; i += 1) {
      if (bs[i] >= ss[n - r]) { ans[i] = '1'; }
      if (bs[i].first and not s[i].first and min(k / 10 + 1, 35) > r and
          bs[i] >= ss[n - r - 1]) {
        ans[i] = '1';
      }
    }
    if (r == n or ss[n - r - 1] == ss[n - r]) {
      print(ans);
      continue;
    }
    int ok = 0;
    for (int i = 0; i < n; i += 1) {
      if (s[i] >= ss[n - r]) {
        if (ws[i] <= ss[n - r - 1]) {
          if (ws[i].first or min((k + 8) / 10, 35) == r) { ok = 1; }
        }
      }
      if (s[i].first == 0) {
        int m = -1;
        for (auto &p : tp[i]) {
          if (not p.empty()) {
            m = max(m, p.back().first + ((int)p.size() - 1) * 20);
          }
        }
        if (m != -1 and Score(1, -m) <= ss[n - r - 1] and
            min(k / 10 + 1, 35) > r) {
          ok = 1;
        }
      }
    }
    if (ok) {
      for (int i = 0; i < n; i += 1) {
        if (s[i] == ss[n - r - 1]) { ans[i] = '1'; }
      }
    }
    print(ans);
  }
}

  

B. Festival Decorating

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef double ld;
const int N=550001,LIM=1028;
const ld pi=acosl(-1.0);
int n,q,mx,i,j,k,x,c,loc[N],col[N],val[N],l,r,ans[N],pos[N];
struct comp{
  ld r,i;comp(ld _r=0,ld _i=0){r=_r,i=_i;}
  void clear(){r=i=0;}
  comp operator+(const comp&x)const{return comp(r+x.r,i+x.i);}
  comp operator-(const comp&x)const{return comp(r-x.r,i-x.i);}
  comp operator*(const comp&x)const{return comp(r*x.r-i*x.i,r*x.i+i*x.r);}
}A0[N],A1[N],A2[N],B0[N],B1[N],B2[N],F[N],w[N],ww[N];
inline void FFT(comp a[],int n,int o){
  for(int i=1;i<n;i++)if(i<pos[i])swap(a[i],a[pos[i]]);
  for(int d=0,k=__builtin_ctz(n);(1<<d)<n;d++){
    int m=1<<d,m2=m<<1;
    for(int i=0;i<n;i+=m2)for(int j=0;j<m;j++){
      comp&A=a[i+j+m],&B=a[i+j],t=(o==1?w[j<<(k-d)]:ww[j<<(k-d)])*A;
      A=B-t;B=B+t;
    }
  }
  if(o==-1)for(int i=0;i<n;i++)a[i].r/=n;
}
inline void solve(int x,int l,int r){
  for(;l<=r;l++)if(val[loc[l]+x]&&col[l]!=val[loc[l]+x]){
    ans[x]=l;
    break;
  }
}
int main(){
  scanf("%d%d",&n,&q);
  for(i=1;i<=n;i++){
    scanf("%d%d",&loc[i],&col[i]);
    val[loc[i]]=col[i];
    if(loc[i]>mx)mx=loc[i];
  }
  for(k=1;k<mx*2;k<<=1);
  j=__builtin_ctz(k)-1;
  for(i=0;i<k;i++)pos[i]=pos[i>>1]>>1|((i&1)<<j);
  for(i=0;i<k;i++)w[i]=comp(cosl(pi*i/k),sinl(pi*i/k));
  for(i=0;i<k;i++)ww[i]=w[i],ww[i].i*=-1;
  for(i=1;i<=n;i++){
    x=loc[i],c=col[i];
    B0[x].r=1;
    B1[x].r=-2*c;
    B2[x].r=((ld)c)*((ld)c);
  }
  FFT(B0,k,1);
  FFT(B1,k,1);
  FFT(B2,k,1);
  l=min(n,LIM);
  for(i=1;i<mx;i++)solve(i,1,l);
  l++;
  while(l<=n){
    r=l*3;
    if(r&1)r--;
    r=min(r,n);
    for(i=0;i<k;i++){
      A0[i].clear();
      A1[i].clear();
      A2[i].clear();
    }
    for(i=l;i<=r;i++){
      x=mx-loc[i],c=col[i];
      A0[x].r=((ld)c)*((ld)c);
      A1[x].r=c;
      A2[x].r=1;
    }
    FFT(A0,k,1);
    FFT(A1,k,1);
    FFT(A2,k,1);
    for(i=0;i<k;i++)F[i]=A0[i]*B0[i]+A1[i]*B1[i]+A2[i]*B2[i];
    FFT(F,k,-1);
    for(i=1;i<mx;i++){
      if(ans[i])continue;
      if(F[mx+i].r>0.5)ans[i]=r/2;
    }
    l=r+1;
  }
  while(q--)scanf("%d",&x),printf("%d\n",ans[x]);
}
/*
[l,3l]
1.5l
*/

  

C. Yet Another Shortest Path Query

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int,int>P;
const int BUF=50000000;
char Buf[BUF],*buf=Buf;
inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
const int OUT=13000000;
char Out[OUT],*ou=Out;int Outn[15],Outcnt;
inline void write(int x){
  if(x==-1){
    *ou++='-';
    *ou++='1';
    return;
  }
  if(!x)*ou++=48;
  else{
    for(Outcnt=0;x;x/=10)Outn[++Outcnt]=x%10+48;
    while(Outcnt)*ou++=Outn[Outcnt--];
  }
}
inline void writeln(int x){write(x);*ou++='\n';}
const int N=1000005,M=N*3,Q=1000005,inf=500000000;
int n,m,cq,i,x,y,z,ans[Q],e[M][3],deg[N],g[N],v[M<<1],nxt[M<<1],ed;
int q[N],h,t,ord[N];bool vis[N];
vector<P>ga[N],gr[N];
inline void add(int x,int y){deg[x]++;v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
inline void ext(int x){if(deg[x]<=5&&!vis[x])vis[q[++t]=x]=1;}
inline void up(int&a,int b){a>b?(a=b):0;}
struct E{int o,x,y,z;E(){}E(int _o,int _x,int _y,int _z){o=_o,x=_x,y=_y,z=_z;}};
int cur,val[N],last[N];
inline void update(int x,int y){if(last[x]!=cur)last[x]=cur,val[x]=y;else up(val[x],y);}
namespace TWO{
const int MAXQ=Q*20;
int ce,cnt[N],pool[MAXQ];E e[MAXQ];
inline void solve(int o,int x,int y,int z){
  if(x==y){up(ans[o],z);return;}
  e[++ce]=E(o,x,y,z);
  cnt[x]++;
  e[++ce]=E(o,y,x,z);
  cnt[y]++;
}
inline void single(int x){
  if(x==cur)return;
  cur=x;
  for(const auto&A:ga[x]){
    update(A.first,A.second);
    for(const auto&B:gr[A.first])update(B.first,A.second+B.second);
  }
}
void run(){
  int i,u;
  for(i=1;i<=n;i++)cnt[i]+=cnt[i-1];
  for(i=1;i<=ce;i++)pool[cnt[e[i].x]--]=i;
  for(cur=0,i=1;i<=n;i++)last[i]=0;
  for(i=1;i<=ce;i++){
    u=pool[i];
    single(e[u].x);
    if(last[e[u].y]==cur)up(ans[e[u].o],val[e[u].y]+e[u].z);
  }
}
}
namespace THREE{
const int MAXQ=Q*2;
int ce,cnt[N],pool[MAXQ];E e[MAXQ];
inline void solve(int o,int x,int y){
  for(const auto&A:gr[x])TWO::solve(o,y,A.first,A.second);
  for(const auto&A:gr[y])TWO::solve(o,x,A.first,A.second);
  e[++ce]=E(o,x,y,0);
  cnt[x]++;
  e[++ce]=E(o,y,x,0);
  cnt[y]++;
}
inline void single(int x){
  if(x==cur)return;
  cur=x;
  for(const auto&A:ga[x])for(const auto&B:gr[A.first]){
    int w=A.second+B.second;
    update(B.first,w);
    for(const auto&C:gr[B.first])update(C.first,w+C.second);
  }
}
void run(){
  int i,u;
  for(i=1;i<=n;i++)cnt[i]+=cnt[i-1];
  for(i=1;i<=ce;i++)pool[cnt[e[i].x]--]=i;
  for(cur=0,i=1;i<=n;i++)last[i]=0;
  for(i=1;i<=ce;i++){
    u=pool[i];
    single(e[u].x);
    if(last[e[u].y]==cur)up(ans[e[u].o],val[e[u].y]);
  }
}
}
int main(){
  fread(Buf,1,BUF,stdin);read(n);read(m);
  for(i=1;i<=m;i++){
    read(x);read(y);read(z);
    e[i][0]=x,e[i][1]=y,e[i][2]=z;
    add(x,y),add(y,x);
  }
  for(h=i=1;i<=n;i++){
    ext(i);
    ga[i].reserve(deg[i]);
    gr[i].reserve(5);
  }
  while(h<=t)for(i=g[x=q[h++]];i;i=nxt[i]){
    y=v[i];
    if(vis[y])continue;
    deg[y]--;
    ext(y);
  }
  for(i=1;i<=n;i++)ord[q[i]]=i;
  for(i=1;i<=m;i++){
    x=e[i][0],y=e[i][1],z=e[i][2];
    if(ord[x]>ord[y])swap(x,y);
    gr[x].emplace_back(P(y,z));
    ga[x].emplace_back(P(y,z));
    ga[y].emplace_back(P(x,z));
  }
  read(cq);
  for(i=1;i<=cq;i++){
    read(x);read(y);
    ans[i]=inf;
    THREE::solve(i,x,y);
  }
  TWO::run();
  THREE::run();
  for(i=1;i<=cq;i++){
    x=ans[i];
    if(x==inf)x=-1;
    writeln(x);
  }
  fwrite(Out,1,ou-Out,stdout);
}

  

D. Operator Precedence

#include "bits/stdc++.h"
using namespace std;
int main()
{
	ios::sync_with_stdio(0); cin.tie(0);
	int T; cin>>T;
	while (T--)
	{
		int n,i;
		cin>>n;
		cout<<2*n-3;
		for (i=1; i<n; i++) cout<<" 2 -1";
		cout<<" 1\n";
	}
}

  

E. Period of a String

#include<bits/stdc++.h>
using namespace std;
int n ;
string s[100005];
struct my_list {
    int num[26] , id;
    my_list() {
        memset(num,0,sizeof(num)) ;
    }
}p[100005];
int L[100005];
bool operator < (const my_list &A,const my_list &B) {
    return A.id < B.id;
}
void solv() {
    cin >> n;
    for(int i = 1;i <= n;i++) {
        cin >> s[i] ;
        memset(p[i].num,0,sizeof(p[i].num)) ;
        L[i] = s[i].size() ;
        for(int j = 0;j < s[i].size();j++) {
            p[i].num[s[i][j] - 'a']++; 
        }
        p[i].id = i;
    }
    set<pair<int,my_list> > st;
    bool ok = 1;
    for(int i = n;i >= 1 && ok;i--) {
        while(st.size() && (--st.end())->first >= L[i] && ok) {
            auto it = st.end() ; it-- ;
            int len = it->first ;
            my_list k = it->second ;
            st.erase(it) ;
 
            int pr = len / L[i] ; len %= L[i] ;
            for(int j = 0;j < 26;j++) {
                if(k.num[j] < 1LL * p[i].num[j] * pr) {ok = 0 ; break ;} ///有可能爆int,记得卡
                k.num[j] -= p[i].num[j] * pr; 
            }
 
            if(len) st.insert({len , k}) ;
        }
        st.insert({L[i] , p[i]}) ;
    }
    if(!ok) {
        cout << "NO\n" ; return ;
    }
    vector<pair<int,my_list> > v(st.begin() , st.end()) ;
 
    string s1 ;
    my_list cur ; 
    for(int i = 0;i < v.size() && ok;i++) {
        // printf("%d : " , v[i].first) ;
        for(int j = 0;j < 26;j++) {
            // printf("%d ",v[i].second.num[j]) ;
            if(v[i].second.num[j] >= cur.num[j]) {
                for(int k = cur.num[j] + 1 ; k <= v[i].second.num[j] ; k++) s1 += (j + 'a') ;
                cur.num[j] = v[i].second.num[j] ;
            }
            else {ok = 0 ; break ;}
        }
        // printf("\n") ;
    }
    if(!ok) {
        cout << "NO\n" ; return ;
    }
    cout << "YES\n" ;
    for(int i = 1 ; i <= n;i++) {
        cout << s1 << '\n' ;
        if(i == n) break ;
        if(L[i + 1] < s1.size()) s1.resize(L[i + 1]) ;
        else {
            int d = s1.size() ;
            for(int j = s1.size() ; j < L[i + 1] ; j++) s1 += (s1[j % d]) ;
        }
    }
    return ;
}
int main() {
    //freopen("in.txt","r",stdin) ;
    ios::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
    int t;cin >> t;
    while(t--) solv() ;
}

  

F. Top Cluster

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=500005,K=21;
const int BUF=30000000;
char Buf[BUF],*buf=Buf;
inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
inline void readll(ll&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
const int OUT=7000000;
char Out[OUT],*ou=Out;int Outn[15],Outcnt;
inline void write(int x){
  if(!x)*ou++=48;
  else{
    for(Outcnt=0;x;x/=10)Outn[++Outcnt]=x%10+48;
    while(Outcnt)*ou++=Outn[Outcnt--];
  }
}
inline void writeln(ll x){write(x);*ou++='\n';}
int n,m,mx,i,j,x,y,z,id[N];
int g[N],v[N<<1],w[N<<1],nxt[N<<1],ed,dfn,loc[N],Log[N<<1];
ll d[N],q[K][N<<1],k;
inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
void dfs(int x,int y){
  q[0][loc[x]=++dfn]=d[x];
  for(int i=g[x];i;i=nxt[i])if(v[i]!=y){
    d[v[i]]=d[x]+w[i];
    dfs(v[i],x);
    q[0][++dfn]=d[x];
  }
}
inline ll lca(int x,int y){
  x=loc[x],y=loc[y];
  if(x>y)swap(x,y);
  int k=Log[y-x+1];
  return min(q[k][x],q[k][y-(1<<k)+1]);
}
inline ll dis(int x,int y){return x==y?0:d[x]+d[y]-lca(x,y)*2;}
struct P{
  int a,b;ll d;
  P(){}
  P(int x){a=b=x,d=0;}
  void add(int x){
    ll now=dis(x,a);
    int na=a,nb=b;
    if(now>d)d=now,na=a,nb=x;
    now=dis(x,b);
    if(now>d)d=now,na=b,nb=x;
    a=na,b=nb;
  }
}dia[N];
inline int ask(int x,ll k){
  int ret=mx+1,l=0,r=mx,mid;
  while(l<=r){
    mid=(l+r)>>1;
    if(dis(x,dia[mid].a)>k||dis(x,dia[mid].b)>k)r=(ret=mid)-1;else l=mid+1;
  }
  return ret;
}
int main(){
  fread(Buf,1,BUF,stdin);
  read(n);read(m);
  for(i=1;i<=n;i++){
    read(x);
    if(x<n)id[x]=i;
  }
  for(i=1;i<n;i++){
    read(x);read(y);read(z);
    add(x,y,z);
    add(y,x,z);
  }
  dfs(1,0);
  for(i=2;i<=dfn;i++)Log[i]=Log[i>>1]+1;
  for(i=1;i<K;i++)for(j=1;j+(1<<i)-1<=dfn;j++)q[i][j]=min(q[i-1][j],q[i-1][j+(1<<(i-1))]);
  for(i=0;i<n;i++){
    x=id[i];
    if(!x)break;
    if(!i)dia[i]=P(x);
    else{
      dia[i]=dia[i-1];
      dia[i].add(x);
    }
    mx=i;
  }
  while(m--){
    read(x);readll(k);
    writeln(ask(x,k));
  }
  fwrite(Out,1,ou-Out,stdout);
}

  

G. Snake Move

#include<cstdio>
typedef unsigned long long ull;
const int N=3005,K=100005,inf=~0U>>1;
int n,m,k,i,j,x,y,sx,sy;
int pos[K][2],lim[N][N],f[N][N],h,t,q[N*N][2];
char a[N][N];
inline void ext(int x,int y,int z){
  if(x<1||x>n||y<1||y>m)return;
  if(a[x][y]=='#')return;
  if(z<lim[x][y]){
    z=lim[x][y];
    if(z<f[x][y])f[x][y]=z;
    return;
  }
  if(z>=f[x][y])return;
  f[x][y]=z;
  q[++t][0]=x;
  q[t][1]=y;
}
inline void branch(int x,int y,int z){
  if(f[x][y]!=z)return;
  z++;
  ext(x-1,y,z);
  ext(x+1,y,z);
  ext(x,y-1,z);
  ext(x,y+1,z);
}
int main(){
  scanf("%d%d%d",&n,&m,&k);
  scanf("%d%d",&sx,&sy);
  for(i=k-1;i;i--){
    scanf("%d%d",&x,&y);
    lim[x][y]=i;
    pos[i][0]=x;
    pos[i][1]=y;
  }
  for(i=1;i<=n;i++)scanf("%s",a[i]+1);
  for(i=1;i<=n;i++)for(j=1;j<=m;j++)f[i][j]=inf;
  ext(sx,sy,0);
  i=1;
  while(1){
    int f1=inf;
    if(h<=t){
      x=q[h][0];
      y=q[h][1];
      f1=f[x][y];
    }
    int f2=i<k?i:inf;
    if(f1==inf&&f2==inf)break;
    if(f1<f2){
      branch(x,y,f1);
      h++;
    }else{
      branch(pos[i][0],pos[i][1],i);
      i++;
    }
  }
  ull ans=0;
  for(i=1;i<=n;i++)for(j=1;j<=m;j++){
    ull tmp=f[i][j];
    //printf("%d%c",f[i][j]==inf?-1:f[i][j],j<m?' ':'\n');
    if(tmp==inf)continue;
    ans+=tmp*tmp;
  }
  printf("%llu",ans);
}

  

H. Sugar Sweet II

#include <bits/stdc++.h>
using namespace std;
int n;
int a[500005] , b[500005] , w[500005];
vector<int> E[500005];
int len[500005];
int st[500005];
bool vis[500005];
void dfs(int u , int d) {
    vis[u] = 1; len[u] = d;
    for(auto v : E[u]) {
        if(!vis[v] && st[v] == 1) dfs(v , d + 1) ;
    }
}
int t[500005];
const int mod = 1e9 + 7;
int fpow(int a,int b) {
    int ans = 1;
    while(b) {
        if(b & 1) ans = 1LL * ans * a % mod;
        a = 1LL*a*a%mod;b >>= 1;
    }
    return ans;
}
void solv() {
    cin >> n;
    for(int i = 1;i <= n;i++) E[i].clear() , len[i] = vis[i] = 0;
    for(int i = 1;i <= n;i++) cin >> a[i];
    for(int i = 1;i <= n;i++) {
        cin >> b[i];
        E[b[i]].push_back(i) ;
    }
    for(int i = 1;i <= n;i++) cin >> w[i];
    for(int i = 1;i <= n;i++) {
        if(i == b[i] || a[i] >= a[b[i]] + w[b[i]]) st[i] = 0 ; ///不会发生
        else if(a[i] >= a[b[i]] && a[i] < a[b[i]] + w[b[i]]) st[i] = 1 ; ///只有父亲发生了才能发生
        else st[i] = 2 ; ///一定发生
    }
    for(int i = 1;i <= n;i++) {
        if(st[i] == 2) dfs(i , 1) ;
    }
    t[0] = 1; t[1] = 1;
    for(int i = 2;i <= n;i++) t[i] = 1LL * (mod - mod / i) * t[mod % i] % mod;
    for(int i = 1;i <= n;i++) t[i] = 1LL * t[i] * t[i - 1] % mod;
 
    for(int i = 1;i <= n;i++) {
        if(len[i]) cout << (a[i] + 1LL * t[len[i]] * w[i]) % mod <<' ';
        else cout << a[i] <<' ';
    }
    cout << '\n' ;
}
int main() {
    // freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false) ; cin.tie(0) ;cout.tie(0) ;
    int t ; cin >> t;
    while(t--) solv() ;
}

  

I. Dreamy Putata

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005,K=5,M=K*2+3,P=1000000007;
int n,m,cnt,q,i,j,op,sx,sy,ex,ey,inv[101];
int pos[N],pl[N][K],pr[N][K],pu[N][K],pd[N][K];
int val[262155][K*2][M],A[K*2][M],B[K*2][M],C[K*2][M],g[M][M],e[M];
bool flag;
const int BUF=30000000;
char Buf[BUF],*buf=Buf;
inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
inline int po(int a,int b){int t=1;for(;b;b>>=1,a=1LL*a*a%P)if(b&1)t=1LL*t*a%P;return t;}
inline void init(int v[][M],int x){
  for(int i=0;i<m;i++){
    v[i][i+m]=1;
/*
E[x,i]=(pl[x][i]*E[x,i-1]+pr[x][i]*E[x,i+1]+pu[x][i]*E[x-1,i]+pd[x][i]*E[x+1,i])/100+1
100*E[x,i]=pl[x][i]*E[x,i-1]+pr[x][i]*E[x,i+1]+pu[x][i]*E[x-1,i]+pd[x][i]*E[x+1,i]+100
pd[x][i]*E[x+1,i]=100*E[x,i]-pl[x][i]*E[x,i-1]-pr[x][i]*E[x,i+1]-pu[x][i]*E[x-1,i]-100
pd[x][i]*E[x+1,i]=100*v[i]-pl[x][i]*E[x,i-1]-pr[x][i]*E[x,i+1]-pu[x][i]*E[x-1,i]-100
*/
    int _inv=inv[pd[x][i]];
    v[i+m][i+m]=100LL*_inv%P;
    v[i+m][(i-1+m)%m+m]=1LL*(P-pl[x][i])*_inv%P;
    v[i+m][(i+1)%m+m]=1LL*(P-pr[x][i])*_inv%P;
    v[i+m][i]=1LL*(P-1LL*pu[x][i])*_inv%P;
    v[i+m][cnt+1]=1LL*(P-100)*_inv%P;
  }
}
inline void copy(int a[][M],int b[][M]){
  for(int i=0;i<cnt;i++)for(int j=0;j<=cnt+1;j++)a[i][j]=b[i][j];
}
inline void merge(int f[][M],int a[][M],int b[][M]){
  static int c[K*2][M];
  for(int i=0;i<cnt;i++){
    for(int j=0;j<=cnt+1;j++)c[i][j]=0;
    c[i][cnt+1]=b[i][cnt+1];
    for(int j=0;j<cnt;j++)for(int k=0;k<=cnt+1;k++)c[i][k]=(1LL*b[i][j]*a[j][k]+c[i][k])%P;
  }
  copy(f,c);
}
void build(int x,int a,int b){
  if(a==b){
    pos[a]=x;
    init(val[x],a);
    return;
  }
  int mid=(a+b)>>1;
  build(x<<1,a,mid);
  build(x<<1|1,mid+1,b);
  merge(val[x],val[x<<1],val[x<<1|1]);
}
inline void change(int o){
  int x=pos[o];
  init(val[x],o);
  for(x>>=1;x;x>>=1)merge(val[x],val[x<<1],val[x<<1|1]);
}
void ask(int x,int a,int b,int c,int d){
  if(c<=a&&b<=d){
    if(!flag)flag=1,copy(B,val[x]);else merge(B,B,val[x]);
    return;
  }
  int mid=(a+b)>>1;
  if(c<=mid)ask(x<<1,a,mid,c,d);
  if(d>mid)ask(x<<1|1,mid+1,b,c,d);
}
inline void mul(int v[][M]){
  static int f[M];
  for(int i=0;i<cnt;i++){
    int w=v[i][cnt+1];
    for(int j=0;j<=cnt;j++)w=(1LL*v[i][j]*e[j]+w)%P;
    f[i]=w;
  }
  for(int i=0;i<cnt;i++)e[i]=f[i];
}
void cal(int x,int a,int b,int c,int d){
  if(c<=a&&b<=d){mul(val[x]);return;}
  int mid=(a+b)>>1;
  if(c<=mid)cal(x<<1,a,mid,c,d);
  if(d>mid)cal(x<<1|1,mid+1,b,c,d);
}
inline void gauss(){
  int i,j,k;
  for(i=0;i<=cnt;i++){
    for(j=i;j<=cnt;j++)if(g[j][i])break;
    if(j!=i)for(k=i;k<=cnt+1;k++)swap(g[i][k],g[j][k]);
    int inv=po(g[i][i],P-2);
    for(j=i+1;j<=cnt;j++){
      int t=1LL*g[j][i]*inv%P;
      for(k=i;k<=cnt+1;k++)g[j][k]=(g[j][k]-1LL*g[i][k]*t)%P;
    }
  }
  for(i=cnt;~i;i--){
    e[i]=g[i][cnt+1];
    for(j=i+1;j<=cnt;j++)e[i]=(e[i]-1LL*g[i][j]*e[j])%P;
    e[i]=1LL*e[i]*po(g[i][i],P-2)%P;
  }
}
inline int query(int sx,int sy,int ex,int ey){
/*
0<=ex<n-1
ask A=[0,ex]
ask B=[ex+1,n-1]
in A:
  we know E(ex,ey)=0
  but E(ex+1,ey) is not right, set it into itself
then merge C=A+B
in C:
  we know the last row, it equals to the first m variables
  we know the row after the last row, it equals to the next m variables
 
then we know the first row, the last row and row ex, row ex+1
 
if sx<=ex, ask[0,sx], use row first&last to get answer
if sx>ex, ask[ex+1,sx] use row ex..ex+1 to get answer
*/
/*
ex==n-1
ask A=[0,n-1]
we know the last row, it equals to the first m variables
we know the row after the last row, it equals to the next m variables, except the ty-th
we know E(ex,ey)=0
ask[0,sx], use row first&last to get answer
*/
  flag=0;
  ask(1,0,n-1,0,ex);
  copy(A,B);
  for(int i=0;i<=cnt+1;i++)A[ey+m][i]=0;
  A[ey+m][cnt]=1;
  if(ex<n-1){
    flag=0;
    ask(1,0,n-1,ex+1,n-1);
    merge(C,A,B);
  }else copy(C,A);
  for(int i=0;i<cnt;i++){
    for(int j=0;j<=cnt;j++)g[i][j]=C[i][j];
    g[i][i]=(g[i][i]-1+P)%P;
    g[i][cnt+1]=(P-C[i][cnt+1])%P;
  }
  for(int i=0;i<=cnt;i++)g[cnt][i]=A[ey][i];
  g[cnt][cnt+1]=(P-A[ey][cnt+1])%P;
  gauss();
  if(sx<=ex)cal(1,0,n-1,0,sx);
  else{
    static int w[M];
    for(int i=0;i<cnt;i++){
      w[i]=A[i][cnt+1];
      for(int j=0;j<=cnt;j++)w[i]=(1LL*A[i][j]*e[j]+w[i])%P;
    }
    for(int i=0;i<cnt;i++)e[i]=w[i];
    cal(1,0,n-1,ex+1,sx);
  }
  return (e[sy]%P+P)%P;
}
int main(){
  for(inv[0]=inv[1]=1,i=2;i<=100;i++)inv[i]=1LL*(P-inv[P%i])*(P/i)%P;
  fread(Buf,1,BUF,stdin);read(n);read(m);
  for(i=0;i<n;i++)for(j=0;j<m;j++)read(pl[i][j]);//(i,j-1)
  for(i=0;i<n;i++)for(j=0;j<m;j++)read(pr[i][j]);//(i,j+1)
  for(i=0;i<n;i++)for(j=0;j<m;j++)read(pu[i][j]);//(i-1,j)
  for(i=0;i<n;i++)for(j=0;j<m;j++)read(pd[i][j]);//(i+1,j)
  cnt=m*2;
  build(1,0,n-1);
  read(q);
  while(q--){
    read(op);read(sx);read(sy);
    if(op==1){
      read(pl[sx][sy]);read(pr[sx][sy]);read(pu[sx][sy]);read(pd[sx][sy]);
      change(sx);
    }else{
      read(ex);read(ey);
      printf("%d\n",query(sx,sy,ex,ey));
    }
  }
}

  

J. Mysterious Tree

#include<bits/stdc++.h>
using namespace std;
int n;
int ask(int u,int v) {
    cout << "? " << u <<' ' << v << endl ;
    int x ; cin >> x;
    return x;
}
void solv() {
    cin >> n;
    int u  = -1, v = -1;
    for(int i = 1;i + 1 <= n;i += 2) {
        if(ask(i , i + 1) == 1) {
            u = i ; v = i + 1 ; break ;
        }
    }
    if(n & 1) {
        if(ask(n , n - 1)== 1) {
            u = n ; v = n - 1;
        }
    }
    if(u == -1) {
        cout << "! 1" << endl ; return ;
    }
    vector<int> vec;
    for(int i = 1;i <= n;i++) {
        if(i != u && i != v) vec.push_back(i) ;
    }
    if(!ask(u , vec[0])) {
        if(!ask(v , vec[0])) {
            cout << "! 1" << endl ; return ;
        }
        swap(u , v);
    }
    if(ask(u , vec[1])) {
        cout << "! 2" << endl ; return ;
    }
    cout << "! 1" << endl ; return ;
}
int main () {
    int t ; cin >> t;
    while(t--) solv() ;
}

  

K. Card Game

#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int a[N] ;
int ch[N * 60][2] ;
int tag[N * 60] ;
int cnt = 0;
int n , q;
int rt[N] ;
int build(int l,int r) {
    int c = ++cnt ;
    tag[c] = 0;
    if(l == r) return c;
    ch[c][0] = build(l , (l + r >> 1)) ;
    ch[c][1] = build((l + r >> 1) + 1, r);
    return c;
}
int modify(int x,int y,int ql,int qr,int l,int r,int tagx,int tagy) { /// [ql,qr]继承x , ++ , < ql继承x , >qr继承y
    if(ql <= l && r <= qr) {
        int c = ++cnt ;
        ch[c][0] = ch[x][0];
        ch[c][1] = ch[x][1] ;
        tag[c] = tag[x] + tagx + 1;
        // printf("on %d %d , tag %d\n",l,r,tag[c]) ;
        return c;
    }
    else if(r < ql) {
        int c = ++cnt ;
        ch[c][0] = ch[x][0];
        ch[c][1] = ch[x][1];
        tag[c] = tagx + tag[x];
        return c;
    }
    else if(l > qr) {
        int c = ++cnt ;
        ch[c][0] = ch[y][0];
        ch[c][1] = ch[y][1];
        tag[c] = tagy + tag[y];
        return c;
    }
    else {
        int md = (l + r >> 1) ;
        int c = ++cnt ;
        ch[c][0] = modify(ch[x][0] , ch[y][0] , ql , qr , l , md , tagx + tag[x] , tagy + tag[y]) ;
        ch[c][1] = modify(ch[x][1] , ch[y][1] , ql , qr , md + 1 , r , tagx + tag[x] , tagy + tag[y]) ;
        return c;
    }
}
int qval(int rt,int pos,int l,int r) {
    if(l == r) return tag[rt] ;
    int md = (l + r >> 1) ;
    if(pos <= md) return tag[rt] + qval(ch[rt][0] , pos , l , md) ;
    else return tag[rt] + qval(ch[rt][1] , pos , md + 1, r) ;
}
int nxt[N] ;
int main() {
    // freopen("in.txt","r",stdin) ;
    // freopen("out2.txt","w",stdout) ;
    ios::sync_with_stdio(false) ; cin.tie(0) ;
    cin >> n >> q;
    for(int i = 1;i <= n;i++) cin >> a[i] ;
    for(int i = 1;i <= n;i++) nxt[i] = n + 1;
    rt[n + 1] = build(1 , n) ;
    for(int i = n;i >= 1;i--) {
        // printf("on %d\n" , i) ;
        rt[i] = modify(rt[i + 1] , rt[min(n+1 , nxt[a[i]] + 1)] , i , nxt[a[i]] - 1, 1 , n , 0 , 0) ;
        nxt[a[i]] = i;
    }
    // cout << qval(rt[3] , 4 , 1 , n) << '\n' ;
    int lans = 0;
    while(q--) {
        int l , r;
        cin >> l >> r;
         l ^= lans ; r ^= lans;
        cout << (lans = qval(rt[l] , r , 1 , n)) << '\n' ;
    }
    return 0;
}

  

L. Master of Both V

#include<bits/stdc++.h>
using namespace std;
 
using ll=long long;
#define fs first
#define sd second
 
const int N=5e5+1e3+7;
 
struct P {
    int x,y;
}a[N],b[N];
 
bool operator <(const P &a,const P &b)
{
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
 
bool operator ==(const P &a,const P &b)
{
    return !(a<b)&&!(b<a);
}
 
P operator -(const P &a,const P &b)
{
    return {a.x-b.x,a.y-b.y};
}
 
ll operator *(const P &a,const P &b)
{
    return 1ll*a.x*b.y-1ll*a.y*b.x;
}
 
ll operator ^(const P &a,const P &b)
{
    return 1ll*a.x*b.x+1ll*a.y*b.y;
}
 
using L=pair<P,P>;
 
int T,n;
 
L mod[N];
 
tuple<int,int,int> e[N];
 
int to[N];
 
int phase(const P &a)
{
    if(a.y!=0)
        return a.y<0;
    return a.x<0;
}
 
bool cmp(const P &a,const P &b)
{
    int pa=phase(a),pb=phase(b);
    if(pa!=pb)
        return pa<pb;
    return a*b>0;
}
 
struct T{
    L lv,rv;
    int ok,cnt;
}t[N*4+1];
 
bool chk(const L &a,const L &b)
{
    if(a==b)
        return 1;
    P u=a.sd-a.fs,v=b.sd-b.fs,w=b.fs-a.sd;
    if(w.x==0&&w.y==0)
        return u*v>0;
    return (u*w>0||(u*w==0&&(u^w)>0))&&(w*v>0||(w*v==0&&(w^v)>0));
}
 
void update(int x)
{
    if(!t[x<<1].cnt)
        t[x]=t[x<<1|1];
    else if(!t[x<<1|1].cnt)
        t[x]=t[x<<1];
    else
    {
        t[x].lv=t[x<<1].lv,t[x].rv=t[x<<1|1].rv;
        t[x].ok=t[x<<1].ok&&t[x<<1|1].ok&&chk(t[x<<1].rv,t[x<<1|1].lv);
        t[x].cnt=t[x<<1].cnt+t[x<<1|1].cnt;
    }
}
 
int id[N];
 
int st[N];
 
multiset<P> seg[N];
 
void adj(L &a,L b)
{
    ll f=(a.sd-a.fs)*(b.fs-a.fs);
    if(f)
    {
        if(f<0)
            swap(a.fs,a.sd);
    }
    else
    {
        f=(a.sd-a.fs)*(b.sd-a.fs);
        if(f<0)
            swap(a.fs,a.sd);
    }
}
 
int m;
 
void modify(int p,L u)
{
    int x=p+m-1;
    if(u.fs==u.sd)
        t[x].cnt=0;
    else
        t[x].ok=1,t[x].cnt=1,t[x].lv=t[x].rv=u;
    x>>=1;
    while(x)
    {
        update(x);
        x>>=1;
    }
}
 
struct MODIFY{
    int r;
    L u;
    int c;
};
 
vector<MODIFY> ch[N],rch[N];
 
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>T;
    while(T--)
    {
        cin>>n;
        vector<tuple<int,int,int> >X;
        for(int i=1;i<=n;i++)
        {
            string op;
            cin>>op;
            if(op=="+")
            {
                cin>>a[i].x>>a[i].y>>b[i].x>>b[i].y;
                ll A=a[i].y-b[i].y,B=b[i].x-a[i].x,C=-1ll*b[i].y*a[i].x+1ll*a[i].y*b[i].x;
                ll g=__gcd(__gcd(A,B),C);
                A/=g,B/=g,C/=g;
                if(A<0||(A==0&&B<0))
                    A*=-1,B*=-1,C*=-1;
                g=abs(__gcd(A,B));
                e[i]={A,B,C};
                X.push_back(e[i]);
            }
            else
            {
                cin>>a[i].x;
                a[i].y=0;
                b[i]=a[i];
            }
        }
        sort(X.begin(),X.end());
        X.erase(unique(X.begin(),X.end()),X.end());
        for(int i=1;i<=X.size();i++)
            seg[i].clear(),st[i]=0;
        for(int i=1;i<=n;i++)
            ch[i].clear(),rch[i].clear();
        for(int i=1;i<=n;i++)
        {
            if(a[i]==b[i])
            {
                int x=id[a[i].x];
                id[i]=x;
                int j=a[i].x;
                seg[x].erase(seg[x].find(a[j]));
                seg[x].erase(seg[x].find(b[j]));
                ch[st[x]].push_back({i-1,mod[st[x]],x});
                if(!seg[x].size())
                    st[x]=0;
                else
                    st[x]=i,mod[i]={*seg[x].begin(),*--seg[x].end()};
            }
            else
            {
                id[i]=lower_bound(X.begin(),X.end(),e[i])-X.begin()+1;
                int x=id[i];
                seg[x].insert(a[i]),seg[x].insert(b[i]);
                mod[i]={*seg[x].begin(),*--seg[x].end()};
                if(st[x])
                    ch[st[x]].push_back({i-1,mod[st[x]],x});
                st[x]=i;
            }
        }
        for(int i=1;i<=X.size();i++)
            if(st[i])
            {
                ch[st[i]].push_back({n,mod[st[i]],i});
                mod[n+1]=mod[st[i]];
            }
        MODIFY mx,smx,rem;
        mx.r=smx.r=-1;
        rem.c=-1;
        for(int i=1;i<=n;i++)
        {
            if(!ch[i].size())
                continue;
            if(rem.c!=-1)
            {
                if(rem.r>=i)
                    ch[i].push_back(rem);
                rem.c=-1;
            }
            sort(ch[i].begin(),ch[i].end(),[&](const MODIFY &u,const MODIFY &v){return u.r>v.r;});
            for(auto [r,u,c]:ch[i])
            {
                MODIFY v={r,u,c};
                if(v.r>mx.r)
                    swap(mx,v);
                if(v.r>smx.r)
                    swap(smx,v);
                if(mx.c==smx.c)
                    swap(v,smx);
            }
            for(auto [r,u,c]:ch[i])
            {
                MODIFY dir;
                if(mx.c!=c)
                    dir=mx;
                else if(smx.c!=c)
                    dir=smx;
                else
                    dir.c=-1;
                if(dir.c==-1||dir.r<i)
                    rem={r,u,c};
                else
                {
                    adj(u,dir.u);
                    rch[i].push_back({min(dir.r,r),u,c});
                    if(dir.r<r)
                        ch[dir.r+1].push_back({r,u,c});
                }
            }
        }
        vector<P> v;
 
        for(int i=1;i<=n;i++)
            for(auto [r,u,c]:rch[i])
                v.push_back({u.sd-u.fs});
        sort(v.begin(),v.end(),cmp);
 
        vector<int> ct(v.size());
        for(int i=1;i<=n;i++)
            ch[i].clear();
        for(int i=1;i<=n;i++)
            for(auto [r,u,c]:rch[i])
            {
                int p=lower_bound(v.begin(),v.end(),u.sd-u.fs,cmp)-v.begin();
                ++ct[p];
                ch[i].push_back({p+ct[p],u,c});
                ch[r+1].push_back({-(p+ct[p]),u,c});
            }
        m=1;
        while(m<v.size())
            m<<=1;
        for(int i=1;i<=m*2-1;i++)
            t[i].cnt=0,t[i].ok=1;
        for(int i=1;i<=n;i++)
        {
            for(auto [r,u,c]:ch[i])
            {
                if(r>0)
                    modify(r,u);
                else
                    modify(-r,{{0,0},{0,0}});
            }
            if(t[1].cnt<=1||(t[1].ok&&chk(t[1].rv,t[1].lv)))
                cout<<1;
            else
                cout<<0;
        }
        cout<<"\n";
    }
 
}

  

M. V-Diagram

#include <bits/stdc++.h>
using namespace std;
using i64 = int64_t;
using f64 = double_t;
int main() {
  cin.tie(nullptr)->sync_with_stdio(0);
  cout << fixed << setprecision(20);
  int t;
  cin >> t;
  for (int ti = 0; ti < t; ti += 1) {
    int n;
    cin >> n;
    vector<i64> a(n);
    for (i64& ai : a) { cin >> ai; }
    int m = min_element(a.begin(), a.end()) - a.begin();
    for (int i = 1; i < n; i += 1) { a[i] += a[i - 1]; }
    f64 ans = 0;
    ans = max(ans, (f64)a.back() / n);
    ans = max(ans, ((f64)a.back() - (m > 1 ? a[m - 2] : 0)) / (n - m + 1));
    ans = max(ans, (f64)a[m + 1] / (m + 2));
    cout << ans << "\n";
  }
}

  

posted @ 2024-02-25 20:07  Claris  阅读(127)  评论(0编辑  收藏  举报