• The 2021 CCPC Guilin Onsite (Grand Prix of EDG)


    题解:

    https://files.cnblogs.com/files/clrs97/2021CCPCguilin.zip

    Code:

    A. A Hero Named Magnus

    #include <bits/stdc++.h>
    #define pb push_back
    #define mp make_pair
    using namespace std;
    int main()
    {
    	int T;
    	cin>>T;
    	while (T--)
    	{
    		long long n;
    		scanf("%lld",&n);
    		printf("%lld\n",2*(n-1)+1);
    	}
    
    	return 0;
    }
    

      

    B. A Plus B Problem

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        int n, q;
        cin >> n >> q;
        vector row(2, vector<int>(n));
        set<int> s;
        for (int i = 0; i < 2; i += 1) {
            string s;
            cin >> s;
            for (int j = 0; j < n; j += 1) row[i][j] = s[j] - '0';
        }
        for (int i = 0; i < n; i += 1) if (row[0][i] + row[1][i] != 9) s.insert(i);
        for (int i = 0, r, c, d; i < q; i += 1) {
            cin >> r >> c >> d;
            r -= 1;
            c -= 1;
            s.erase(c);
            auto it = s.lower_bound(c);
            int p = it != s.end() and row[0][*it] + row[1][*it] >= 10;
            int org = row[0][c] + row[1][c] + p;
            row[r][c] = d;
            int cur = row[0][c] + row[1][c] + p;
            cout << cur % 10 << " ";
            if (org == cur) cout << "0\n";
            else if ((org < 10) ^ (cur < 10)) cout << 2 + c - (it == s.begin() ? 0 : *prev(it)) << "\n";
            else cout << "2\n";
            if (cur - p != 9) s.insert(c);
        }
        return 0;
    }
    

      

    C. AC Automaton

    #include<bits/stdc++.h>
    using namespace std;
     
    typedef long long ll;
     
    const int N=3e5+1e3+7,S=1833;
     
    typedef pair<int,int> pii;
    #define fs first
    #define sd second
    #define mp make_pair
     
    int n,q;
     
    vector<int>g[N];
     
    char s[N];
     
    struct BIT{
        int c[N];
     
        void add(int x,int v)
        {
            while(x<=n)
            {
                c[x]+=v;
                x+=x&-x;
            }
        }
     
        int qry(int x)
        {
            int ret=0;
            while(x)
            {
                ret+=c[x];
                x-=x&-x;
            }
            return ret;
        }
    }T[3];
     
    int st[N],ed[N],fa[N];
     
    int dc;
     
    void dfs(int x)
    {
        st[x]=++dc;
        for(auto v:g[x])
            dfs(v);
        ed[x]=dc;
    }
     
    ll ans;
     
    int val[N];
     
    int cp[N];
     
    char ch[N];
     
    int tag[N],bel[N],bid,app[N],last[N],up[N];
     
    vector<int>h[N];
     
    struct Edge{
        int ne,to;
    }edg[N];
     
    int ct,head[N];
     
    void build(int u,int v)
    {
        ++ct;
        edg[ct].to=v;
        edg[ct].ne=head[u];
        head[u]=ct;
    }
     
    int lp[N],rv[N];
     
    int sz[N],ps[N],ord[N],pi;
     
    void go(int x)
    {
        ps[x]=++pi;
        ord[pi]=x;
        sz[x]=1;
        for(int tmp=head[x];tmp;tmp=edg[tmp].ne)
            go(edg[tmp].to),sz[x]+=sz[edg[tmp].to];
    }
     
    void ss()
    {
        for(int x=1;x<=n;x++)
        {
            for(auto v:g[x])
                lp[v]=tag[x]?x:lp[x];
        }
        for(int x=n;x>=1;x--)
        {
            rv[x]=0;
            int sv=-1;
            for(auto v:g[x])
            {
                rv[x]+=rv[v]>0;
                if(rv[v]>0)
                    sv=v;
            }
            int cnt=rv[x];
            if(tag[x])
                bel[x]=++bid;
            else
            {
                if(cnt==0)
                {
                    if(lp[x])
                    {
                        if(!app[lp[x]])
                            app[lp[x]]=++bid,bel[x]=bid;
                            
                        else
                            bel[x]=app[lp[x]];
                    }
                    else
                        bel[x]=0;
                }
                else if(cnt==1)
                {
                    if(sv==-1)
                        while(1);
                    if(tag[sv])
                        bel[x]=++bid;
                    else
                        bel[x]=bel[sv];
                }
                else
                    bel[x]=++bid;
            }
            if(tag[x])
                rv[x]++;
            for(auto v:g[x])
                if(bel[v]!=bel[x]&&bel[v]&&bel[x]&&!up[bel[v]])
                    build(bel[x],bel[v]),up[bel[v]]=bel[x];
        }
        pi=0;
        go(bel[1]);
    }
     
    int vis[S*4][S*2+1];
     
    int cnt[S*4],ts[S*4];
     
     
    void godownadd(int pid)
    {
        if(!pid)
            return;
        for(int t=ps[pid]+1;t<=ps[pid]+sz[pid]-1;t++)
        {
            int x=ord[t];
            ans-=cnt[x];
            cnt[x]-=vis[x][-ts[x]+1+S];
            ts[x]--;
        }
        // for(int tmp=head[pid];tmp;tmp=edg[tmp].ne)
        //     godownadd(edg[tmp].to);
    }
     
    void godowndel(int pid)
    {
        if(!pid)
            return;
        for(int t=ps[pid]+1;t<=ps[pid]+sz[pid]-1;t++)
        {
            int x=ord[t];
            ts[x]++;
            cnt[x]+=vis[x][-ts[x]+1+S];
            ans+=cnt[x];
        }
        // for(int tmp=head[pid];tmp;tmp=edg[tmp].ne)
        //     godowndel(edg[tmp].to);
    }
     
    void goup(int pid,int v)
    {
        if(v==1){
            while(pid){
                ts[pid]++;
                cnt[pid]+=vis[pid][-ts[pid]+1+S];
                ans+=cnt[pid];
                pid=up[pid];
            }
        }else{
            while(pid){
                ans-=cnt[pid];
                cnt[pid]-=vis[pid][-ts[pid]+1+S];
                ts[pid]--;
                pid=up[pid];
            }
        }
    }
     
    void ins(int x,int v)
    {
        //part 1 
        if(s[x]=='A')
        {
            ans+=(T[0].qry(ed[x])-T[0].qry(st[x]))*v;
            T[1].add(st[x]+1,v);
            T[1].add(ed[x]+1,-v);
        }
        else
        {
            ans+=T[1].qry(st[x])*v;
            T[0].add(st[x],v);
        }
        if(s[x]=='?')
        {
            if(val[x]>=-S&&val[x]<=S)
                vis[bel[x]][val[x]+S]+=v;
            if(val[x]+ts[bel[x]]>0)
                ans+=(val[x]+ts[bel[x]])*v,cnt[bel[x]]+=v;
        }
    }
     
    void chg1(int x,char ol,char nw)
    {
        int v=(nw!='C')-(ol!='C');
        if(v==1)
            godownadd(bel[x]);
        else if(v==-1)
            godowndel(bel[x]);
        v=(nw!='A')-(ol!='A');
        if(v)
            goup(up[bel[x]],v);
    }
    
    /*
    void ins(int x,int v)
    {
        //part 1 
        if(s[x]=='A')
        {
            ans+=(T[0].qry(ed[x])-T[0].qry(st[x]))*v;
            T[1].add(st[x]+1,v);
            T[1].add(ed[x]+1,-v);
        }
        else
        {
            ans+=T[1].qry(st[x])*v;
            T[0].add(st[x],v);
        }
        if(s[x]=='?')
        {
            if(val[x]>=-S&&val[x]<=S)
                vis[bel[x]][val[x]+S]+=v;
            if(val[x]+ts[bel[x]]>0)
                ans+=(val[x]+ts[bel[x]])*v,cnt[bel[x]]+=v;
        }
        if(s[x]=='?'||s[x]=='A'){
            if(v==1)
                godownadd(bel[x]);
                // for(int tmp=head[bel[x]];tmp;tmp=edg[tmp].ne)
                //     godownadd(edg[tmp].to);
            else
                godowndel(bel[x]);
                // for(int tmp=head[bel[x]];tmp;tmp=edg[tmp].ne)
                    // godowndel(edg[tmp].to);
        }
        if(s[x]=='?'||s[x]=='C')
            goup(up[bel[x]],v);
    }
    */
    
    int main()
    {
        scanf("%d%d",&n,&q);
        scanf("%s",s+1);
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&fa[i]);
            g[fa[i]].push_back(i);
        }
        dfs(1);
        for(int x=1;x<=n;x++)
        {
            if(s[x]=='A')
            {
                T[1].add(st[x]+1,1);
                T[1].add(ed[x]+1,-1);
            }
            else
                T[0].add(st[x],1);
            if(s[x]=='A'||s[x]=='?')
            {
                T[2].add(st[x]+1,1);
                T[2].add(ed[x]+1,-1);
            }
        }
        for(int i=1;i<=n;i++)
            if(s[i]=='A')
                ans+=T[0].qry(ed[i])-T[0].qry(st[i]-1);
        for(int i=1;i<=n;i++)
        {
            val[i]=T[0].qry(ed[i])-T[0].qry(st[i])-T[2].qry(st[i]);
            if(val[i]>0&&s[i]=='?')
                ans+=val[i];
        }
        for(int i=1;i<=q;i++)
            scanf("%d%s",&cp[i],ch+i);
        for(int i=1;i<=q;i+=S)
        {
            int j=min(i+S-1,q);
            for(int k=i;k<=j;k++)if(k==i||s[cp[k]]!=ch[k])
                tag[cp[k]]=1,app[cp[k]]=0;
            for(int k=0;k<=bid;k++)
                head[k]=0,up[k]=0;
            ct=0;
            bid=0;
            // dfs(1,0);
            ss();
            for(int t=0;t<=bid;t++)
                ts[t]=0,cnt[t]=0;
            for(int k=1;k<=n;k++)
            {
                if(s[k]=='?')
                {
                    if(val[k]>=-S&&val[k]<=S)
                        vis[bel[k]][val[k]+S]++;
                    if(val[k]>0)
                        cnt[bel[k]]++;
                }
            }
            for(int k=i;k<=j;k++)
            {
                int x=cp[k];
                char c=ch[k];
                if(s[x]!=c)
                {
                    chg1(x,s[x],c);
                    ins(x,-1);
                    s[x]=c;
                    ins(x,1);
                }
                printf("%lld\n",ans);
            }
            for(int k=1;k<=n;k++)
            {
                if(val[k]>=-S&&val[k]<=S)
                    vis[bel[k]][val[k]+S]=0;
                if(bel[k])
                    val[k]+=ts[bel[k]];
                bel[k]=0;
            }
            for(int k=i;k<=j;k++)
                tag[cp[k]]=0;
        }
    }
    

      

    D. Assumption is All You Need

    #include<bits/stdc++.h>
    #define rep(i,n) for(int i=1;i<=n;++i)
    #define trav(a,x) for(auto&a:x)
    #define all(x) begin(x),end(x)
    #define sz(x) (int)(x).size()
    #define pb push_back
    #define mp make_pair
    #define x0 fuckhel
    #define y0 fuckoscar
    #define x1 fucksub
    #define y1 fuckzzy
    #define st first
    #define nd second
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef pair<int,int> pr;
    typedef vector<int> vi;
    const int N=2050,mod=1e9+7;
    int a[N],b[N],Pa[N],Pb[N],T,n,top;
    pr s[N*N/2];
    bool sol(){
        top=0;
        rep(i,n)
            if(Pa[i]<Pb[i])
                return 0;
            else{
                for(int j=i+1;j<=n;++j)
                    if(Pb[i]<=Pa[j]&&Pa[j]<Pa[i]){
                        s[++top]=mp(Pa[j],Pa[i]);
                        swap(Pa[i],Pa[j]);
                    }
            }
        return 1;
    }
    int main(){
        for(scanf("%d",&T);T--;){
            scanf("%d",&n);
            rep(i,n)scanf("%d",a+i),Pa[a[i]]=i;
            rep(i,n)scanf("%d",b+i),Pb[b[i]]=i;
            if(sol()){
                printf("%d\n",top);
                rep(i,top)printf("%d %d\n",s[i].st,s[i].nd);
            }else puts("-1");
        }
        return 0;
    }
    

      

    E. Buy and Delete

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef pair<int,int>P;
    const int N=2005,M=5005,inf=~0U>>1;
    int n,m,c,mi,ans,S,i,j,x,y,z,g[N],u[M],v[M],w[M],nxt[M],d[N];
    priority_queue<P,vector<P>,greater<P> >q;
    inline void up(int&a,int b){a>b?(a=b):0;}
    inline void ext(int x,int y){
      if(d[x]<=y)return;
      q.push(P(d[x]=y,x));
    }
    int main(){
      scanf("%d%d%d",&n,&m,&c);
      mi=ans=inf;
      for(i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        up(mi,z);
        u[i]=x;
        v[i]=y;
        w[i]=z;
        nxt[i]=g[x];
        g[x]=i;
      }
      for(S=1;S<=n;S++){
        for(i=1;i<=n;i++)d[i]=inf;
        ext(S,0);
        while(!q.empty()){
          P t=q.top();q.pop();
          if(d[t.second]<t.first)continue;
          for(i=g[t.second];i;i=nxt[i])ext(v[i],t.first+w[i]);
        }
        for(i=1;i<=m;i++)if(d[u[i]]<inf&&v[i]==S)up(ans,d[u[i]]+w[i]);
      }
      if(c<mi)puts("0");
      else if(c<ans)puts("1");
      else puts("2");
    }
    

      

    F. Illuminations II

    #include <bits/stdc++.h>
    using namespace std;
    using LL = long long;
    struct P{
        LL x, y;
        P operator - (const P& p) const {return {x - p.x, y - p.y};}
        LL cross(const P& p) const {return x  * p.y - y * p.x;}
        double norm() const {return hypot(x, y);}
    };
    int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        cout << fixed << setprecision(20);
        int n, m;
        cin >> n >> m;
        vector<P> p(n), q(m);
        for (auto& [x, y] : p) cin >> x >> y;
        for (auto& [x, y] : q) cin >> x >> y;
        vector<double> s(n), ss(n);
        for (int i = 0; i < n; i += 1) {
            ss[i] = s[i] = (p[i] - p[(i + 1) % n]).norm();
            if (i) ss[i] += ss[i - 1];
        }
        auto intersection = [&](const P& A, const P& B, const P& C, const P& D) -> P {
            LL x = (C - A).cross(D - C), y = (B - A).cross(D - C);
            if (y < 0) {
                x = -x;
                y = -y;
            }
            return {x, y};
        };
        auto intersect = [&](const P& A, const P& B, int i) -> optional<double> {
            const P &C = p[i], &D = p[(i + 1) % n];
            if ((B - A).cross(D - C) == 0) return nullopt;
            if(intersection(A, B, C, D).x < 0) return nullopt;
            auto [x, y] = intersection(C, D, A, B);
            if (x >= y or x < 0) return nullopt;
            return (i ? ss[i - 1] : 0) + s[i] / y * x;
        };
        int f = 0, t = 0;
        double ans = 0;
        for (int i = 0; i < m; i += 1) {
            const P &A = q[i], &B = q[(i + 1) % m];
            while (not intersect(B, A, f).has_value()) f = (f + 1) % n;
            while (not intersect(A, B, t).has_value()) t = (t + 1) % n;
            double df = intersect(B, A, f).value(), dt = intersect(A, B, t).value();
            if (dt < df) dt += ss.back();
            ans += (A - B).norm() * (dt - df);
        }
        cout << ans / ss.back();
        return 0;
    }
    

      

    G. Occupy the Cities

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int T;
    char s[1000010];
    
    int main() {
        scanf("%d",&T);
        while(T--) {
            int n;
            scanf("%d",&n);
            scanf("%s",s + 1);
            vector<int> idx;
            for (int i = 1; i <= n; i++) {
                if (s[i] == '1') idx.push_back(i);
            }
            assert(idx.size());
            if (idx.size() == n) {
                puts("0");
                continue;
            }
            int max_gap = max(idx[0] - 1, n - idx[idx.size() - 1]);
            for (int i = 1; i < idx.size(); i++) {
                max_gap = max(max_gap, (idx[i] - idx[i - 1] - 1) / 2);
            }
            auto check = [&](int x) {
                int R = 0;
                for (auto &t : idx) {
                    if (R < t - x - 1) return false;
                    if (R == t - x - 1) {
                        R = max(R, t + x - 1);
                    } else {
                        R = max(R, t + x);
                    }
                }
                return R >= n;
            };
            for (int i = max_gap; ; i++) {
                if (check(i)) {
                    printf("%d\n",i);
                    break;
                }
            }
        }
    }
    

      

    H. Popcount Words

    #include<cstdio>
    typedef long long ll;
    const int N=100005,M=100005,LEN=500005,K=30;
    int n,m,i,j,k,x,y,l[N],r[N],L[K],R[K],at[M];
    int tot,son[LEN][2],fail[LEN],q[LEN];
    ll ans[LEN],f[K+1][LEN][2],tmp;
    int g[K+1][LEN][2];
    inline int ins(){
      static char s[LEN];
      scanf("%s",s);
      int x=0;
      for(int i=0;s[i];i++){
        int w=s[i]-'0';
        if(!son[x][w])son[x][w]=++tot;
        x=son[x][w];
      }
      return x;
    }
    void make(){
      int h=1,t=0,i,j,x;
      fail[0]=-1;
      for(i=0;i<2;i++)if(son[0][i])q[++t]=son[0][i];
      while(h<=t){
        x=q[h++];
        for(i=0;i<2;i++){
          if(son[x][i]){
            fail[son[x][i]]=son[fail[x]][i];
            q[++t]=son[x][i];
          }else son[x][i]=son[fail[x]][i];
        }
      }
    }
    inline void decode(int x,int*f){
      for(int i=K-1;~i;i--){
        f[i]=x&1;
        x>>=1;
      }
    }
    int dfs(int x,int s,int el,int er,int o){
      if((!el&&!er)||(o==K)){
        f[o][x][s]++;
        return g[o][x][s];
      }
      for(int i=0;i<2;i++){
        int nel=el,ner=er;
        if(el){
          if(i<L[o])continue;
          if(i>L[o])nel=0;
        }
        if(er){
          if(i>R[o])continue;
          if(i<R[o])ner=0;
        }
        x=dfs(x,s^i,nel,ner,o+1);
      }
      return x;
    }
    int main(){
      scanf("%d%d",&n,&m);
      for(i=1;i<=n;i++)scanf("%d%d",&l[i],&r[i]);
      for(i=1;i<=m;i++)at[i]=ins();
      make();
      for(i=0;i<=tot;i++)for(j=0;j<2;j++)g[K][i][j]=son[i][j];
      for(i=K-1;i;i--)for(j=0;j<=tot;j++)for(k=0;k<2;k++){
        x=j;
        for(y=0;y<2;y++)x=g[i+1][x][k^y];
        g[i][j][k]=x;
      }
      x=0;
      for(i=1;i<=n;i++){
        decode(l[i],L);
        decode(r[i],R);
        x=dfs(x,0,1,1,0);
      }
      for(i=1;i<K;i++)for(j=0;j<=tot;j++)for(k=0;k<2;k++){
        tmp=f[i][j][k];
        if(!tmp)continue;
        for(x=j,y=0;y<2;y++){
          f[i+1][x][k^y]+=tmp;
          x=g[i+1][x][k^y];
        }
      }
      for(i=0;i<=tot;i++)for(j=0;j<2;j++)ans[g[K][i][j]]+=f[K][i][j];
      for(i=tot;i;i--)ans[fail[q[i]]]+=ans[q[i]];
      for(i=1;i<=m;i++)printf("%lld\n",ans[at[i]]);
    }
    

      

    I. PTSD

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    int n;
    char s[1000100];
    
    int main() {
        int T;
        scanf("%d",&T);
        while(T--) {
            scanf("%d", &n);
            scanf("%s", s + 1);
            LL ans = 0;
            int cnt = 0;
            for (int i = n; i >= 1; i--) {
                if (s[i] == '1' && cnt > 0) {
                    cnt--;
                    ans += i;
                } else {
                    cnt++;
                }
            }
            printf("%lld\n",ans);
        }
    }
    

      

    J. Suffix Automaton

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<set>
    #include<unordered_map>
    #include<unordered_set>
    #include<map>
    #include<cassert>
    #include<string>
    using namespace std;
    #define pb push_back
    #define mp make_pair
    #define rep(i,n) for(int i=1;i<=n;i++)
    typedef long long LL;
    namespace SuffixTree
    {
    	const int inf=1<<25,S=27,N=1000010;
    	int root,last,pos,need,remain,acnode,ace,aclen;
    	struct node{int st,en,lk,son[S];int len(){ return min(en,pos+1)-st;}}tree[N<<1];
    	int n;char text[N],tmp[N];
    	int new_node(int st,int en=inf)
    	{
    		node nd;
    		nd.st=st;nd.en=en;
    		for(int i=nd.lk=0;i<S;i++)nd.son[i]=0;
    		tree[++last]=nd;
    		return last;
    	}
    	char acedge(){ return text[ace];}
    	void addedge(int node)
    	{
    		if (need)tree[need].lk=node;
    		need=node;
    	}
    	bool down(int node)
    	{
    		if (aclen>=tree[node].len()){
    			ace+=tree[node].len(),aclen-=tree[node].len(),acnode=node;
    			return 1;
    		}
    		return 0;
    	}
    	void init()
    	{
    		need=last=remain=ace=aclen=0;
    		root=acnode=new_node(pos=-1,-1);
    	}
    	void extend(char c)
    	{
    		text[++pos]=c;need=0;remain++;
    		while (remain)
    		{
    			if (!aclen)ace=pos;
    			if (!tree[acnode].son[acedge()])
    			{
    				tree[acnode].son[acedge()]=new_node(pos);
    				addedge(acnode);
    			}else
    			{
    				int nxt=tree[acnode].son[acedge()];
    				if (down(nxt))continue;
    				if (text[tree[nxt].st+aclen]==c){aclen++;addedge(acnode);break;}
    				int split=new_node(tree[nxt].st,tree[nxt].st+aclen);
    				tree[acnode].son[acedge()]=split;
    				tree[split].son[c]=new_node(pos);
    				tree[nxt].st+=aclen;
    				tree[split].son[text[tree[nxt].st]]=nxt;
    				addedge(split);
    			}
    			remain--;
    			if (acnode==root&&aclen)aclen--,ace=pos-remain+1;
    			else acnode=tree[acnode].lk?tree[acnode].lk:root;
    			
    		}
    	}
    	int tot;
    	void dfs(int x,int dep,vector<int>g[],int ansl[])
    	{
    		if(x!=root)
    		{
    			int l=tree[x].st-dep+1;ansl[++tot]=l;
    			g[dep+1].pb(tot);
    			dep+=tree[x].len();
    			g[dep+1].pb(-tot);
    		}
    		for(int i=0;i<S;i++)if(tree[x].son[i])dfs(tree[x].son[i],dep,g,ansl);
    	}
    	void main(int& _n,int&m,vector<int>g[],int ansl[])
    	{
    		init();
    		scanf("%s",tmp+1);
    		n=strlen(tmp+1);
    		for(int i=1;i<=n;i++)extend(tmp[i]-'a'); extend(26);
    		pos--;
    		dfs(root,0,g,ansl);
    		_n=n;m=tot;
    	}
    }
    const int N=1000010;
    vector<int>g[N];
    vector<pair<int,int>>Q[N];
    pair<int,int>ans[N];
    int n,m,q,tree[N<<3],ansl[N<<1];
    LL sum[N];
    void modify(int p,int le,int ri,int x,int y)
    {
    	tree[p]+=y;
    	if(le==ri)return;
    	int mid=(le+ri)>>1;
    	if(x<=mid)modify(p<<1,le,mid,x,y);
    	else modify(p<<1|1,mid+1,ri,x,y);
    }
    int get(int p,int le,int ri,int k)
    {
    	if(le==ri)return le;
    	int mid=(le+ri)>>1;
    	if(tree[p<<1]>=k)return get(p<<1,le,mid,k);
    	else return get(p<<1|1,mid+1,ri,k-tree[p<<1]);
    }
    int main()
    {
    	SuffixTree::main(n,m,g,ansl);
    	rep(i,n)for(auto j:g[i])sum[i]+=j>0?1:-1;
    	rep(i,n)sum[i]+=sum[i-1];
    	rep(i,n)sum[i]+=sum[i-1];
    	scanf("%d",&q);
    	rep(i,q)
    	{
    		LL k;scanf("%lld",&k);
    		int len=lower_bound(sum+1,sum+n+1,k)-sum;
    		if(len>n)ans[i]=mp(-1,-1);
    		else Q[len].pb(mp(k-sum[len-1],i));
    	}
    	rep(i,n)
    	{
    		for(auto j:g[i])modify(1,1,m,abs(j),j>0?1:-1);
    		for(auto j:Q[i])
    		{
    			int l=ansl[get(1,1,m,j.first)];
    			ans[j.second]=mp(l,l+i-1);
    		}
    	}
    	rep(i,q)printf("%d %d\n",ans[i].first,ans[i].second);
        return 0;
    }
    

      

    K. Tax

    #include<cstdio>
    const int N=55,M=N*N,inf=~0U>>1;
    int n,m,i,j,x,y,z,w[M],g[N][N],h,t,q[N],d[N];
    int pool[N][N],cnt[N],ans[N],vis[M],cur;
    void dfs(int dis,int x){
      if(ans[x]>cur)ans[x]=cur;
      dis++;
      for(int i=1;;i++){
        int y=pool[dis][i];
        if(!y)break;
        int z=g[x][y];
        if(!z)continue;
        vis[z]++;
        cur+=vis[z]*w[z];
        dfs(dis,y);
        cur-=vis[z]*w[z];
        vis[z]--;
      }
    }
    int main(){
      scanf("%d%d",&n,&m);
      for(i=1;i<=m;i++)scanf("%d",&w[i]);
      while(m--){
        scanf("%d%d%d",&x,&y,&z);
        g[x][y]=g[y][x]=z;
      }
      q[h=t=1]=1;
      d[1]=1;
      while(h<=t){
        x=q[h++];
        for(i=1;i<=n;i++)if(g[x][i]&&!d[i]){
          d[i]=d[x]+1;
          q[++t]=i;
        }
      }
      for(i=1;i<=n;i++)pool[d[i]][++cnt[d[i]]]=i;
      for(i=1;i<=n;i++)ans[i]=inf;
      dfs(1,1);
      for(i=2;i<=n;i++)printf("%d\n",ans[i]);
    }
    

      

    L. Wiring Engineering

    #include<cstdio>
    const int N=505,M=300005,inf=1000000000;
    int n,m,i,j,a[N],b[N],w[N][N],q[M],pool[M];
    int pre[N][N],suf[N][N],g[N][N],h[N][N];
    struct E{int al,ar,bl,br,ans;}e[M];
    inline void umin(int&a,int b){a>b?(a=b):0;}
    inline void up(int&a,int b){a<b?(a=b):0;}
    inline void init(int A,int B,int C,int D,int f[][N]){
      int i,j;
      A--,B++,C--,D++;
      for(i=A;i<=B;i++)for(j=C;j<=D;j++)f[i][j]=g[i][j]=h[i][j]=-inf;
    }
    inline void back(int A,int B,int C,int D,int f[][N]){
      int i,j,k,t;
      for(i=B;i>=A;i--)for(j=D;j>=C;j--){
        k=-inf;
        up(k,f[i+1][j]);
        up(k,g[i][j+1]);
        t=w[i][j]-b[j];
        up(k,g[i][j+1]+t);
        up(k,h[i+1][j]+t);
        up(g[i][j],k);
        
        k=-inf;
        up(k,f[i][j+1]);
        up(k,h[i+1][j]);
        t=w[i][j]-a[i];
        up(k,g[i][j+1]+t);
        up(k,h[i+1][j]+t);
        up(h[i][j],k);
        
        k=-inf;
        up(k,f[i+1][j]);
        up(k,f[i][j+1]);
        up(k,g[i][j]-a[i]);
        up(k,h[i][j]-b[j]);
        up(f[i][j],k);
      }
    }
    inline void go(int A,int B,int C,int D,int f[][N]){
      int i,j,k;
      for(i=A;i<=B;i++)for(j=C;j<=D;j++){
        k=f[i][j];
        up(f[i+1][j],k);
        up(f[i][j+1],k);
        up(g[i][j],k-a[i]);
        up(h[i][j],k-b[j]);
        
        k=g[i][j];
        up(f[i+1][j],k);
        up(g[i][j+1],k);
        k+=w[i][j]-b[j];
        up(g[i][j+1],k);
        up(h[i+1][j],k);
        
        k=h[i][j];
        up(f[i][j+1],k);
        up(h[i+1][j],k);
        k+=w[i][j]-a[i];
        up(g[i][j+1],k);
        up(h[i+1][j],k);
      }
    }
    void solvecol(int A,int B,int C,int D,int L,int R);
    void solverow(int A,int B,int C,int D,int L,int R){
      if(A>B||C>D||L>R)return;
      int m=(A+B)>>1,i,j,k,o,cp=0,xl,xr,yl,yr;
      xl=yl=n+1,xr=yr=0;
      for(i=L;i<=R;i++){
        o=q[i];
        if(e[o].al<=m&&e[o].ar>=m){
          umin(xl,e[o].al);
          up(xr,e[o].ar);
          umin(yl,e[o].bl);
          up(yr,e[o].br);
          pool[++cp]=o;
        }
      }
      for(i=yl;i<=yr;i++){
        init(xl,m,yl,i,pre);
        h[m][i]=0;
        back(xl,m,yl,i,pre);
        init(m,xr,i,yr,suf);
        h[m][i]=0;
        go(m,xr,i,yr,suf);
        for(k=1;k<=cp;k++){
          o=pool[k];
          if(e[o].bl<=i&&e[o].br>=i)up(e[o].ans,pre[e[o].al][e[o].bl]+suf[e[o].ar][e[o].br]);
        }
      }
      int _L=L-1,_R=R+1;
      for(i=L;i<=R;i++){
        o=q[i];
        if(e[o].ar<m)pool[++_L]=o;
        if(e[o].al>m)pool[--_R]=o;
      }
      for(i=L;i<=R;i++)q[i]=pool[i];
      solvecol(A,m-1,C,D,L,_L);
      solvecol(m+1,B,C,D,_R,R);
    }
    void solvecol(int A,int B,int C,int D,int L,int R){
      if(A>B||C>D||L>R)return;
      int m=(C+D)>>1,i,j,k,o,cp=0,xl,xr,yl,yr;
      xl=yl=n+1,xr=yr=0;
      for(i=L;i<=R;i++){
        o=q[i];
        if(e[o].bl<=m&&e[o].br>=m){
          umin(xl,e[o].al);
          up(xr,e[o].ar);
          umin(yl,e[o].bl);
          up(yr,e[o].br);
          pool[++cp]=o;
        }
      }
      for(i=xl;i<=xr;i++){
        init(xl,i,yl,m,pre);
        g[i][m]=0;
        back(xl,i,yl,m,pre);
        init(i,xr,m,yr,suf);
        g[i][m]=0;
        go(i,xr,m,yr,suf);
        for(k=1;k<=cp;k++){
          o=pool[k];
          if(e[o].al<=i&&e[o].ar>=i)up(e[o].ans,pre[e[o].al][e[o].bl]+suf[e[o].ar][e[o].br]);
        }
      }
      int _L=L-1,_R=R+1;
      for(i=L;i<=R;i++){
        o=q[i];
        if(e[o].br<m)pool[++_L]=o;
        if(e[o].bl>m)pool[--_R]=o;
      }
      for(i=L;i<=R;i++)q[i]=pool[i];
      solverow(A,B,C,m-1,L,_L);
      solverow(A,B,m+1,D,_R,R);
    }
    int main(){
      scanf("%d%d",&n,&m);
      for(i=1;i<=n;i++)scanf("%d",&a[i]);
      for(i=1;i<=n;i++)scanf("%d",&b[i]);
      for(i=1;i<=n;i++)for(j=1;j<=n;j++)scanf("%d",&w[i][j]);
      for(i=1;i<=m;i++){
        scanf("%d%d%d%d",&e[i].al,&e[i].ar,&e[i].bl,&e[i].br);
        e[i].ar++,e[i].br++;
        q[i]=i;
      }
      solverow(1,n+1,1,n+1,1,m);
      for(i=1;i<=m;i++)printf("%d\n",e[i].ans);
    }
    

      

  • 相关阅读:
    mock中测试private方法,不是mock
    PHP检测每一段代码执行时间
    Cannot find autoconf. Please check your autoconf installation and the $PHP_AUTOCONF environment variable. Then, rerun this script.
    php返回HTTP状态码
    PHP获取今天、昨天、明天的日期
    memcache及其telnet命令使用详解
    PHP的json_encode中文被转码的问题
    PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
    php pack()函数详解与示例
    socket编程原理
  • 原文地址:https://www.cnblogs.com/clrs97/p/15805782.html
Copyright © 2020-2023  润新知