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);
}

  

posted @ 2022-01-14 22:57  Claris  阅读(364)  评论(0编辑  收藏  举报