CSP21

wlesq發表於2024-08-15

總結:兩個題的checker我都自己寫了一個,MD,耽誤太多時間了,\(Linux\)\(checker\)使用要加g++ checker.cpp -o 程式名

image

這題,性質題,首先發現一個樹\(n-1\)條邊,每次刪偶數條邊,所以\(n\)必須是奇數,其次我們發現優先刪去深度深的點較為優,刪完後,我們發現還剩下一些散點散樹,再\(dfs\)一遍刪掉即可
若先消除根節點,其葉子節點要是無法消除就wa了,所以貪心消除最靠近葉子的節點

點選檢視程式碼
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define pb push_back
#define ull unsigned long long
#define pii pair<int,int>
#define lid (rt<<1)
#define rid (rt<<1|1)
#define ts cout<<"-------------------"<<endl
using namespace std;
const int N = 2e5+5;
int n,p[N],rt,in[N],dep[N],sz[N],id[N];std::vector<int> edge[N];
bool vis[N];
void dfs1(int u)
{
	// cout<<in[u]<<" "<<u<<" "<<sz[u]<<endl;
	for(auto to:edge[u])
	{
		if(to==p[u])continue;
		dfs1(to);
	}
	if(in[u]%2==0)//回溯的時候刪除,相當於從優先下往上刪
	{
		in[u]=0;
		for(auto to:edge[u])in[to]--;
		cout<<u<<endl;
		vis[u]=1;
	}
}
void dfs2(int u)
{
	// if(!u)return;
	// cout<<u<<endl;
	if(in[u]%2==0&&!vis[u])//第二遍可以從上往下刪
	{
		in[u]=0;
		vis[u]=1;
		cout<<u<<endl;
		for(auto to:edge[u])in[to]--;
		// return;
	}
	for(auto to:edge[u])
	{
		if(to==p[u])continue;
		dfs2(to);
	}
}	
int main()
{
	speed();
	// freopen("T1.in","r",stdin);
	// freopen("in.in","r",stdin);
	// freopen("out.out","w",stdout);
	cin>>n;
	// cout<<n<<endl;
	for(int i=1;i<=n;i++)
	{
		cin>>p[i];
		// cout<<p[i]<<" ";
		if(p[i])edge[p[i]].pb(i),in[p[i]]++,in[i]++,edge[i].pb(p[i]);//連雙向邊刪父親
		else rt=i;
	}
	// cout<<endl;
	if(n%2==0)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	cout<<"YES"<<endl;
	// dfs(rt);
	// sort(id+1,id+1+n,[&](auto a,auto b){
	// 	return dep[a]>dep[b];
	// });
	dfs1(rt);
	dfs2(rt);
	return 0;
}
/*
10
0 1 1 2 2 3 3 4 4 7
*/

image
建出最短路樹,然後優先刪深的就行了

點選檢視程式碼
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define pb push_back
#define ull unsigned long long
#define pii pair<int,int>
#define lid (rt<<1)
#define rid (rt<<1|1)
#define ts cout<<"-------------------"<<endl
using namespace std;
const int N = 3e5+5;
struct Id
{
	ll to,w,id;
}pre[N];
vector <Id> edge[N];
vector <int> e[N];
ll n,m,k,dis[N],in[N];bool vis[N];
struct node
{
	ll u,dis;
	bool operator < (const node& A)const
	{
		return dis>A.dis;
	}
};
void dij()
{
	for(int i=1;i<=n;i++)dis[i]=1e12;
	priority_queue <node> q;
	q.push({1,0});dis[1]=0;
	while(q.size())
	{
		int u=q.top().u;q.pop();
		if(vis[u])continue;
		vis[u]=1;
		for(auto [to,w,id]:edge[u])
		{
			if(dis[to]>dis[u]+w)
			{
				dis[to]=dis[u]+w;
				pre[to].to=u;
				pre[to].id=id;
				q.push({to,dis[to]});				
			}
		}
	}
}
int dep[N],mx;
vector <int> t[N];
void dfs(int u)
{
	dep[u]=dep[pre[u].to]+1;
	mx=max(mx,dep[u]);
	if(u!=1)t[dep[u]].pb(pre[u].id);
	for(auto to:e[u])
	{
		// cout<<u<<"->"<<to<<endl;
		dfs(to);
	}
}
void put(int u)
{
	if(u!=1)cout<<pre[u].id<<" ";
	for(auto to:e[u])
	{
		if(!k)break;
		k--;
		put(to);
	}
}
int main()
{
	speed();
	// freopen("T2.in","r",stdin);
	// freopen("in.in","r",stdin);
	// freopen("out.out","w",stdout);
	cin>>n>>m>>k;ll u,v,w;
	for(int i=1;i<=m;i++)
	{
		cin>>u>>v>>w;
		edge[u].pb({v,w,i});edge[v].pb({u,w,i});
	}
	dij();
	for(int i=2;i<=n;i++)e[pre[i].to].pb(i);
	if(k>=n-1)
	{
		cout<<n-1<<endl;
		for(int i=2;i<=n;i++)cout<<pre[i].id<<" ";
	}else
	{
		dfs(1);
		cout<<k<<endl;
		bool f=0;
		put(1);
	}
	return 0;
}

image

考場暴力,點不水?

點選檢視程式碼
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define pb push_back
#define ull unsigned long long
#define pii pair<int,int>
#define lid (rt<<1)
#define rid (rt<<1|1)
#define ts cout<<"-------------------"<<endl
using namespace std;
const int N = 1e6+6;
inline int read()
{
	int x=0,f=1;char ch=getchar_unlocked();
	for(;ch<'0'||ch>'9';ch=getchar_unlocked())ch=='-'?f=-1:f=f;
	for(;ch>='0'&&ch<='9';ch=getchar_unlocked())x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
inline void write(ll x)
{
	return x<0?(putchar_unlocked('-'),write(-x),void(0)):(x==0?void(0):(write(x/10),putchar_unlocked((x%10)|48),void(0)));
}
int n,m,Q;
struct OP
{
	int op,l,r;ll w;
}op[N];
struct st
{
	int l,r;ll w,lz;
}st[N<<2];
inline void pu(int rt)
{
	st[rt].w=st[lid].w+st[rid].w;
}
inline void bt(int rt,int l,int r)
{
	st[rt].l=l;st[rt].r=r;
	st[rt].lz=-1;
	if(l==r)
	{
		st[rt].w=0;return;
	}
	int mid=l+r>>1;
	bt(lid,l,mid);bt(rid,mid+1,r);
	pu(rt);
}
inline void pd(int rt)
{
	if(st[rt].lz!=-1)
	{
		int lz=st[rt].lz;st[rt].lz=-1;
		st[lid].lz=lz;st[rid].lz=lz;
		st[lid].w=lz;st[rid].w=lz;
	}
}
inline void update(int rt,int l,int r,int val)
{
	if(l<=st[rt].l&&st[rt].r<=r)
	{
		st[rt].w=val;
		st[rt].lz=val;
		return;
	}
	pd(rt);
	int mid=(st[rt].l+st[rt].r)>>1;
	if(l<=mid)update(lid,l,r,val);
	if(r>mid)update(rid,l,r,val);
	pu(rt);
	return;
}
inline ll query(int rt,int pos)
{
	if(st[rt].l==st[rt].r)
	{
		return st[rt].w;
	}
	pd(rt);
	ll ans=0;
	int mid=(st[rt].l+st[rt].r)>>1;
	if(pos<=mid)ans+=query(lid,pos);
	else if(pos>mid)ans+=query(rid,pos);	
	// pu(rt);
	return ans;
}
struct node
{
	int l,r,id;;
	bool operator < (const node& A)const
	{
		return id<A.id;
	}
};
int sq,B;
inline void solve()
{
	int l,r;
	for(int i=1;i<=Q;i++)
	{
		l=read();r=read();
		vector <int> a(n+1,0);
		ll ans=0;
		for(int j=l;j<=r;j++)
		{
			if(op[j].op==1)swap(a[op[j].l],a[op[j].r]);
			else if(op[j].op==2)
			{
				for(int k=op[j].l;k<=op[j].r;k++)
				{
					a[k]=op[j].w;
				}

			}else 
			{
				ans+=a[op[j].l];
			}
		}

	}
}
inline void solve2()
{
	int l,r;
	bt(1,1,n);
	for(int i=1;i<=Q;i++)
	{
		l=read();r=read();
		update(1,1,n,0);
		// bt(1,1,n);
		ll ans=0;
		for(int j=l;j<=r;j++)
		{
			if(op[j].op==1)
			{
				// swap(a[op[j].l],a[op[j].r]);
				int t1=query(1,op[j].l),t2=query(1,op[j].r);
				update(1,op[j].l,op[j].l,t2);update(1,op[j].r,op[j].r,t1);
			}
			else if(op[j].op==2)
			{
				update(1,op[j].l,op[j].r,op[j].w);
			}else 
			{
				ans+=query(1,op[j].l);
			}
		}
		// cout<<
		ans==0?putchar_unlocked('0'),void(0):write(ans);
		putchar_unlocked('\n');
	}	
}
int main()
{
	// freopen("T3.in","r",stdin);
	// freopen("in.in","r",stdin);
	// freopen("out.out","w",stdout);
	n=read();m=read();Q=read();
	for(int i=1;i<=m;i++)
	{
		op[i].op=read();
		if(op[i].op==1)
		{
			op[i].l=read();op[i].r=read();
			continue;
		}else if(op[i].op==2)
		{
			op[i].l=read();op[i].r=read();op[i].w=read();
		}else op[i].l=read();
	}
	int l,r;
	solve2();
	return 0;
}

image

逆天,\(hash\)記憶化得了\(80\)

點選檢視程式碼
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define pb push_back
#define ull unsigned long long
#define pii pair<int,int>
#define lid (rt<<1)
#define rid (rt<<1|1)
#define ts cout<<"-------------------"<<endl
using namespace std;
const int N = 5e6+5;const ull B=233;
string s[N];
int n,m;ull p[600005],len[N];
vector <ull> hs[N];
unordered_map <int,unordered_map<int,int>> f;
inline int read()
{
	int x=0,f=1;char ch=getchar_unlocked();
	for(;ch<'0'||ch>'9';ch=getchar_unlocked())ch=='-'?f=-1:f=f;
	for(;ch>='0'&&ch<='9';ch=getchar_unlocked())x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
inline void write(int x)
{
	return x<0?(putchar_unlocked('-'),write(-x),void(0)):(x==0?void(0):(write(x/10),putchar_unlocked((x%10)|48),void(0)));
}
inline void calc(int id,int len)
{
	// cout<<len<<endl;
	hs[id].resize(len+1,0);
	for(int i=1;i<=len;i=-~i)
	{
		hs[id][i]=hs[id][i-1]*B+s[id][i-1]-'a';
		if(!p[i])p[i]=p[i-1]*B;
	}
}
inline ull get(int id,int l,int r)
{
	return hs[id][r]-hs[id][l-1]*p[r-l+1]; 
}
inline int fen(int x,int y)
{
	int r=min(len[x],len[y]);
	for(int i=r;i>=1;i--)
	{
		if(get(y,1,i)==get(x,len[x]-i+1,len[x]))return i;
	}
	return 0;
}
int main()
{
	// freopen("T4.in","r",stdin);
	// freopen("in.in","r",stdin);
	// freopen("out.out","w",stdout);
	n=read();m=read();
	p[0]=1;
	for(int i=1;i<=n;i=-~i)
	{
		cin>>s[i];
		// __builtin_scanf("%s",s[i]);
		// if(i<=2)cout<<s[i]+1<<endl;
		len[i]|=s[i].size();
		calc(i,len[i]);
	}
	int l,r;
	for(int i=1;i<=m;i=-~i)
	{
		l=read();r=read();//l houzhui
		if(f[l][r])
		{
			f[l][r]==-1?putchar_unlocked('0'),void(0):write(f[l][r]);
			putchar_unlocked('\n');
			continue;
		}
		f[l][r]=fen(l,r);
		if(f[l][r]==0)f[l][r]=-1;
		f[l][r]==-1?putchar_unlocked('0'),void(0):write(f[l][r]);
		putchar_unlocked('\n');
	}
	return 0;
}