• UR #19 简要题解


    比赛总结

    开场把 ( ext{T1}) 读成一道不可做,然后又成功写完 ( ext{T2})(log) 的做法后以为过不了,并且成功的傻逼的以为正确的 (n^3) 做法思路没法做,以至 (2.5h) 后才写完两道的 (170)。最后十分钟才发现自己读错题,只好打出 ( ext{GG})

    省选这样的话就可以退役了。

    T1

    (m+1) 的限制不用管。可以发现如果只有环的操作充要条件是只考虑 (1) 的边度数全部相等。于是变量就只有 (n) 个。二分图可以拆成每个点分别操作。

    高斯消元即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 510;
    bitset<N> b[N];
    
    int n,m,deg[N],val[N];
    
    void guass(){
    	for(int i=1;i<=n;i++){
    		if(!b[i][i]){
    			int p=0;
    			for(int j=i+1;j<=n;j++)if(b[j][i]){p=j;break;}
    			if(!p)continue;
    			swap(b[i],b[p]);
    		}
    		for(int j=1;j<=n;j++)if(i^j){
    			if(b[j][i])b[j]^=b[i];
    		}
    	}
    	for(int i=1;i<=n;i++)if(!b[i][i]&&b[i][n+1]){
    		puts("no");
    		return ;
    	}
    	puts("yes");
    }
    
    void Main(){
    	cin >> n >> m;
    	for(int i=1;i<=n;i++)b[i].reset();
    	for(int i=1;i<=n;i++)deg[i]=0,val[i]=0;
    	for(int i=1;i<=m;i++){
    		int u,v,w;scanf("%d%d%d",&u,&v,&w);
    		b[u][v] = b[v][u] = 1;
    		deg[u]^=1,deg[v]^=1;
    		if(w)val[u]^=1,val[v]^=1;
    	}
    	for(int i=1;i<=n;i++)b[i][i]=deg[i],b[i][n+1]=val[i];
    	guass();
    }
    
    int main()
    {
    	int T;cin >> T;
    	while(T--){
    		Main();
    	}
    }
    

    T2

    简要题解:猎人杀,没了

    拆成每个点的贡献,之后就是这个位置需要 (a) 个,其它位置需要 (b) 个,概率就是这个位置不是最后填满的概率。

    容斥之后发现只需要算 (f_{i,j}) 表示 (i) 个人分 (j) 个东西,人和东西有标号,每个人不能分到 (ge b) 个。

    (NTT) 去做背包即可 (O(n^3log n))

    当然这个有一个 (O(n^3))( ext{dp}),我们考虑最后一个物品放给谁,然后现在不合法的情况只有一种:某个人分到了恰好 (b) 个。

    然后转移就是 (O(1)) 的了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod = 998244353;
    int add(int a,int b){a+=b;return a>=mod?a-mod:a;}
    int sub(int a,int b){a-=b;return a<0?a+mod:a;}
    int mul(int a,int b){return (ll)a*b%mod;}
    int qpow(int a,int b){int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;}
    /* math */
    int n,a,b;
    
    typedef vector<int> Poly;
    namespace Ploy_template {
    	int rev[4000010];
    	Poly Add(Poly a,Poly b){
    		a.resize(max(a.size(),b.size()));
    		for(size_t i=0;i<b.size();i++)a[i] = add(a[i],b[i]);
    		return a;
    	}
    	Poly Sub(Poly a,Poly b){
    		a.resize(max(a.size(),b.size()));
    		for(size_t i=0;i<b.size();i++)a[i] = sub(a[i],b[i]);
    		return a;
    	}
    	Poly rever(Poly x){
    		reverse(x.begin(),x.end());
    		return x;
    	}
    	inline void DFT(int *t,int n,int tpe){
    		int l=0;while(1<<l<n)++l;
    		for(int i=1;i<n;i++) rev[i] = (rev[i>>1]>>1)|((i&1)<<(l-1));
    		for(int i=0;i<n;i++) if(rev[i]>i) swap(t[rev[i]],t[i]);
    		for(int step=1;step<n;step<<=1){
    			int wn = qpow(3, (mod-1)/(step<<1));
    			for(int i=0;i<n;i+=step<<1){
    				int w = 1;
    				for(int j=0;j<step;j++,w = mul(w,wn)){
    					int x = t[i+j], y = mul(w,t[i+j+step]);
    					t[i+j] = add(x,y); t[i+j+step] = sub(x,y);
    				}
    			}
    		}
    		if(tpe==1)return ;
    		for(int i=1;i<n-i;i++)swap(t[i],t[n-i]);
    		int inv = qpow(n,mod-2);
    		for(int i=0;i<n;i++)t[i] = mul(t[i], inv);
    	}
    	inline Poly NTT(Poly a, int n, Poly b, int m){
    		int len = n+m-1,l=0;while(1<<l<len)++l;
    		static Poly res;
    		res.resize(1<<l); a.resize(1<<l),b.resize(1<<l);
    		DFT(&a[0],1<<l,1),DFT(&b[0],1<<l,1);
    		for(int i=0;i<(1<<l);i++)res[i] = mul(a[i],b[i]);
    		DFT(&res[0],1<<l,-1);
    		res.resize(len);
    		return res;
    	}
    	Poly NTT(Poly a, Poly b){
    		return NTT(a,a.size(),b,b.size());
    	}
    }
    using namespace Ploy_template;
    
    const int N = 260;
    int ifac[N*N],fac[N*N];
    inline void init(int n=250*260){
    	ifac[0]=fac[0]=1;for(int i=1;i<=n;i++)fac[i]=mul(fac[i-1],i);
    	ifac[n]=qpow(fac[n],mod-2);for(int i=n-1;i;i--)ifac[i]=mul(ifac[i+1],i+1);
    }
    Poly f;
    Poly g[N];
    
    inline int binom(int a,int b){
    	if(a<b)return 0;
    	return mul(fac[a],mul(ifac[b],ifac[a-b]));
    }
    
    void output(Poly& t){
    	for(size_t i=0;i<t.size();i++)cout << t[i] << " ";puts("");
    }
    
    Poly multar(Poly a,Poly b){
    	Poly c(a.size(),0);
    	for(size_t i=0;i<a.size();i++)c[i]=mul(a[i],b[i]);
    	return c;
    }
    
    int main()
    {
    	init();
    	cin >> n >> a >> b;
    	f.resize(b);
    	for(int i=0;i<b;i++)f[i] = ifac[i];
    	int Lenth = (n-1)*(b-1)+1;
    	int len = 1;
    	while(Lenth>len)len<<=1;
    	f.resize(len);
    	DFT(&f[0],len,1);
    	g[0].resize(len);
    	for(int i=0;i<len;i++)g[0][i]=1;
    	for(int i=1;i<=n-1;i++)g[i]=multar(g[i-1],f);
    	int ret=0;//for debug
    	for(int i=0;i<n;i++){
    		DFT(&g[i][0],len,-1);
    		int d = qpow(i+1,mod-2);
    		int P = qpow(d,a);
    		P=mul(P,binom(n-1,i));
    		if(i&1){P=sub(0,P);}
    		for(int j=0;j<len;j++){
    			int q = mul(g[i][j],fac[j]);
    			q = mul(q, binom(a-1+j,a-1));
    			q=mul(P,q);
    			ret=add(ret,q);
    			P=mul(P,d);
    		}
    	}
    	cout << mul(sub(1,ret),n) << endl;
    }
    

    T3

    从后向前,维护下标为时间的后缀 (min) 以及修改次数。

    这玩意是 Segment Tree Beats。

    代码(被卡常)

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e6+6;
    
    
    namespace FastIO {
    	#define SIZE 100000
    	inline char nc(){
    		// return getchar();
    		static char buf[SIZE],*p1=buf+SIZE,*p2=buf+SIZE;
    		if(p1==p2) p2=(p1=buf)+fread(buf,1,SIZE,stdin);
    		return p1==p2?-1:*p1++;
    	}
    	inline bool blank(char ch){return ch==' '||ch=='
    '||ch=='
    '||ch=='	';}
    	template <class T> inline void read(T &x){
    		register double tmp = 1;
    		register bool sign = 0;
    		x = 0;
    		register char ch=nc();
    		for(;ch<'0'||ch>'9';ch=nc()) if(ch=='-') sign=1;
    		for(;ch>='0'&&ch<='9';ch=nc()) x=x*10+ch-'0';
    		if(ch=='.') for(ch=nc();ch>='0'&&ch<='9';ch=nc()) tmp/=10.0,x+=tmp*(ch-48);
    		if(sign) x=-x;
    	}
    	inline void read(char *s){
    		register char ch=nc();
    		for (;blank(ch);ch=nc());
    		for (;!blank(ch);ch=nc()) *s++=ch;
    		*s=0;
    	}
    	inline void read(char &c){
    		for(c=nc();blank(c);c=nc());
    	}
    	template <class T> inline void print(T x){
    		if(x<0) putchar('-'),x=-x;
    		if(x>9) print(x/10);
    		putchar('0'+x%10);
    	}
    	template <class T> inline void print(T x,char c){
    		print(x),putchar(c);
    	}
    }
    using namespace FastIO;
    
    int n,m;
    struct dat{
    	int mx,secmx,Add;
    }t[N<<2];
    
    #define mid ((l+r)>>1)
    inline void pushup(int x){
    	if(t[x<<1].mx>t[x<<1|1].mx){
    		t[x].mx=t[x<<1].mx;
    		t[x].secmx=max(t[x<<1].secmx,t[x<<1|1].mx);
    	}else{
    		t[x].mx=t[x<<1|1].mx;
    		if(t[x<<1].mx==t[x<<1|1].mx){
    			t[x].secmx=max(t[x<<1|1].secmx,t[x<<1].secmx);
    		}else t[x].secmx=max(t[x<<1|1].secmx,t[x<<1].mx);
    	}
    }
    inline void adval(int x,int val,int Ad){
    	if(t[x].mx>val){
    		t[x].mx=val;
    		t[x].Add+=Ad;
    	}
    }
    inline void pushdown(int x){
    	if(t[x].Add){
    		adval(x<<1,t[x].mx,t[x].Add);
    		adval(x<<1|1,t[x].mx,t[x].Add);
    		t[x].Add=0;
    	}
    }
    
    inline void build(int x,int l,int r){
    	t[x].mx=1<<30, t[x].secmx=-(1<<30);
    	if(l==r)return ;
    	build(x<<1,l,mid),build(x<<1|1,mid+1,r);
    }
    
    inline void Ad(int x,int x1){
    	if(t[x].secmx<x1){
    		adval(x,x1,1);return ;
    	}pushdown(x);
    	Ad(x<<1,x1);
    	Ad(x<<1|1,x1);
    	pushup(x);
    }
    
    inline void modify(int x,int l,int r,int ql,int qr,int v){
    	// if(x==1)cout << ql << " " << qr << " " << v << endl;
    	if(ql<=l&&qr>=r){Ad(x,v);return;}
    	pushdown(x);
    	if(ql<=mid)modify(x<<1,l,mid,ql,qr,v);
    	if(qr>mid) modify(x<<1|1,mid+1,r,ql,qr,v);
    	pushup(x);
    }
    
    inline int query(int x,int l,int r,int p){
    	if(l==r)return t[x].Add;
    	pushdown(x);
    	if(p<=mid)return query(x<<1,l,mid,p);
    	else return query(x<<1|1,mid+1,r,p);
    }
    typedef pair<int,int> pi;
    pair<int, pair<pi,int> > opt[N<<1];
    int c1;
    int a[N];int lst[N];
    pair<int,pi> q[N];
    int c2;
    int ans[N];
    
    int M=1;
    
    int main()
    {
    	read(n),read(m);
    	build(1,1,m);
    	for(int i=1;i<=n;i++){
    		read(a[i]);
    		lst[i]=1;
    	}
    	for(int i=1,op,x,v;i<=m;i++){
    		read(op);
    		ans[i] = -1;
    		if(op==1){
    			read(x),read(v);
    			opt[++c1]=make_pair(x,make_pair(pi(lst[x],M),a[x]));
    			a[x] = v;
    			lst[x]=++M;
    		}else{
    			read(x);
    			q[++c2]=make_pair(x,make_pair(M,i));
    		}
    	}
    	for(int i=1;i<=n;i++){
    		opt[++c1]=make_pair(i,make_pair(pi(lst[i],M),a[i]));
    	}
    	sort(opt+1,opt+c1+1),sort(q+1,q+c2+1);
    	build(1,1,M);
    	for(int i=n,l,r,v;i;i--){
    		while(c1&&opt[c1].first==i){
    			l=opt[c1].second.first.first,r=opt[c1].second.first.second,v=opt[c1].second.second;
    			if(l<=r)modify(1,1,M,l,r,v);
    			--c1;
    		}
    		while(c2&&q[c2].first==i){
    			ans[q[c2].second.second]=query(1,1,M,q[c2].second.first);
    			--c2;
    		}
    	}
    	for(int i=1;i<=m;i++){
    		if(ans[i]!=-1){
    			print(ans[i],'
    ');
    		}
    	}
    }
    
  • 相关阅读:
    XML文件的解析—DOM、SAX
    JSP :使用<%@include%>报Duplicate local variable path 错误
    XML文件的DTD编写
    DOM生成XML文件
    ArrayList增加扩容问题 源码分析
    实时事件统计项目:优化flume:用file channel代替mem channel
    CDH离线数据导入solr:利用MapReduceIndexerTool将json文件批量导入到solr
    solrconfig.xml介绍
    Solr Update插件自定义Update Chain按条件更新索引
    实时事件统计项目:优化solr和morphline的时间字段
  • 原文地址:https://www.cnblogs.com/weiyanpeng/p/12637761.html
Copyright © 2020-2023  润新知