• 【简要题解】洛谷 7 月月赛 Div.1


    【简要题解】洛谷 7 月月赛 Div.1

    P6687 论如何玩转 Excel 表格

    把两个状态的每偶数列上下交换一下,旋转操作就变成邻项交换了。

    //@winlere
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<map>
    #include<unordered_map>
    
    using namespace std; typedef long long ll;
    int qr(){
    	int ret=0,c=getchar(),f=0;
    	while(!isdigit(c)) f|=c==45,c=getchar();
    	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    const int maxn=1e6+5;
    int a[2][maxn],b[2][maxn],id;
    vector< pair<int,int> > A,B;
    unordered_map< ll, int > qwq;
    int seg[maxn],data[maxn],n;
    
    void add(int pos,int val){
    	for(int t=pos;t<=n;t+=t&-t) seg[t]+=val;
    }
    
    int que(int pos){
    	int ret=0;
    	for(int t=pos;t>0;t-=t&-t) ret+=seg[t];
    	return ret;
    }
    
    int main(){
    	n=qr(); 
    	for(int t=0;t<2;++t)
    		for(int i=1;i<=n;++i) a[t][i]=qr();
    	for(int t=0;t<2;++t)
    		for(int i=1;i<=n;++i) b[t][i]=qr();
    	for(int t=1;t<=n;++t){
    		if(t&1) A.push_back({a[0][t],a[1][t]});
    		else A.push_back({a[1][t],a[0][t]});
    		if(t&1) B.push_back({b[0][t],b[1][t]});
    		else B.push_back({b[1][t],b[0][t]});
    	}
    	qwq.reserve(n<<1);
    	for(int t=1;t<=n;++t) qwq[((ll)B[t-1].first<<30)+B[t-1].second]=t;
    	for(int t=1;t<=n;++t){
    		auto g=qwq.find(((ll)A[t-1].first<<30)+A[t-1].second);
    		if(g==qwq.end()) return puts("dldsgay!!1"),0;
    		data[t]=g->second;
    	}
    	ll ans=0;
    	for(int t=1;t<=n;++t)
    		ans+=t-1ll-que(data[t]),add(data[t],1);
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
    

    P6688 可重集

    将数字(i)变成(x^{a_i}),设(F(l,r)=sum_{iin[l,r]}x^{a_i})。判断两个是否本质相同变成了判断(F(l,r)=F(L,R) imes x^{min(l,r)-min(L,R)}),哈希下就行。注意到种子要比(a_i)

    三哈,二哈,单哈都可以过

    //@winlere
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    
    using namespace std; typedef long long ll;
    int qr(){
    	int ret=0,c=getchar(),f=0;
    	while(!isdigit(c)) f|=c==45,c=getchar();
    	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    const int maxn=1e6+5;
    
    const ll mod1=1e18+3;
    const ll mod2=207132529660813483ll;
    const ll mod3=14285714285715727ll;
    const ll seed1=19260817;
    const ll seed2=19491001;
    const ll seed3=9137669;
    typedef ll E;
    
    ll MOD1(const ll&a){return a>=mod1?a-mod1:a;}
    ll MOD1(const ll&a,const ll&b){return (__int128)a*b%mod1;}
    
    E mi[maxn],seed(seed1);
    int a[maxn],n,m;
    
    namespace QWQ{
    #define mid ((l+r)>>1)
    #define lef l,mid,pos<<1
    #define rgt mid+1,r,pos<<1|1
    	int seg[maxn<<2];
    	E f[maxn<<2];
    	void pp(int pos){seg[pos]=min(seg[pos<<1],seg[pos<<1|1]);f[pos]=MOD1(f[pos<<1]+f[pos<<1|1]);}
    	void build(int l,int r,int pos){
    		if(l==r) return seg[pos]=a[l],f[pos]=mi[a[l]],void();
    		build(lef); build(rgt); pp(pos);
    	}
    	void upd(int p,int v,int l,int r,int pos){
    		if(p<l||p>r) return;
    		if(l==r) return seg[pos]=v,f[pos]=mi[v],void();
    		if(p<=mid) upd(p,v,lef);
    		else upd(p,v,rgt);
    		pp(pos);
    	}
    	pair<int,E> que(int L,int R,int l,int r,int pos){
    		if(L>r||R<l) return {1e9,0};
    		if(L<=l&&r<=R) return {seg[pos],f[pos]};
    		auto t1=que(L,R,lef),t2=que(L,R,rgt);
    		return {min(t1.first,t2.first),MOD1(t1.second+t2.second)};
    	}
    #undef mid
    #undef lef
    #undef rgt
    }
    
    int main(){
    	n=qr(),m=qr();
    	mi[0]={1};
    	for(int t=1;t<=1e6;++t) mi[t]=MOD1(mi[t-1],seed);
    	for(int t=1;t<=n;++t)
    		a[t]=qr();	
    	QWQ::build(1,n,1);
    	for(int t=1;t<=m;++t){
    		int op=qr();
    		if(op==0){
    			int x=qr(),y=qr();
    			QWQ::upd(x,y,1,n,1);
    		}
    		if(op==1){
    			int l=qr(),r=qr(),L=qr(),R=qr();
    			auto LL=QWQ::que(l,r,1,n,1),RR=QWQ::que(L,R,1,n,1);
    			E t1=LL.second,t2=RR.second;
    			int TT1=LL.first,TT2=RR.first;
    			if(TT1>TT2) t2=MOD1(t2,mi[TT1-TT2]);
    			if(TT1<TT2) t1=MOD1(t1,mi[TT2-TT1]);
    			if(t1==t2) puts("YES");
    			else puts("NO");
    		}
    	}
    	return 0;
    }
    

    P6689 序列

    任何一个有(i)个右括号的括号序列被那个算法生成的概率是一样的,先设(dp(i,j))表示已经填了(i)个括号其中(j)个是左括号的概率。

    转移是

    [dp(i,j)={n-i+1over n}dp(i-1,j-1)+sum_{j=i}^n { j imes (j-1) imes (j-2)dots imes i=j^{underline {j-i+1}} over n^{j-i+2}}(n-i+1) ]

    可以简单做到(O(n^2))

    现在还少一个东西,那就是一个有(f_j=j)个右括号的长度为(n)的括号序列期望有多少匹配(括号匹配指方案数是卡特兰数那种匹配)数,枚举一对括号匹配在哪个地方并且产生一的贡献,可以发现这一对括号匹配之间必须完美匹配,方案数是卡特兰数。

    [f_j=sum_{i=2}^n sum_{j=0}^{lfloor{i-2over 2} floor} C_j {n-2j-2choose t-1-j}= sum_{j=0}^{lfloor{n-2over 2} floor} C_j (n-(2j-2)+1){n-2j-2choose t-1-j} ]

    复杂度(O(n^2))

    //@winlere
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<initializer_list>
    
    using namespace std; typedef long long ll;
    int qr(){
    	int ret=0,c=getchar(),f=0;
    	while(!isdigit(c)) f|=c==45,c=getchar();
    	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    const int maxn=5015;
    const int mod=998244353;
    int jc[maxn<<1],inv[maxn<<1],invc[maxn<<1],dp[maxn][maxn],f[maxn<<1],temp[maxn],mi[maxn];
    int MOD(const int&x,const int&y){return 1ll*x*y%mod;}
    int MOD(const int&x){return x>=mod?x-mod:x;}
    int MOD(const initializer_list<int>&ve){int ret=1;for(auto t:ve) ret=MOD(ret,t); return ret;}
    
    int ksm(const int&ba,const int&p){
    	int ret=1;
    	for(int t=p,b=ba;t;t>>=1,b=MOD(b,b))
    		if(t&1) ret=MOD(ret,b);
    	return ret;		
    }
    void pre(const int&n){
    	jc[0]=inv[0]=1; jc[1]=inv[1]=invc[1]=1;
    	for(int t=2;t<=n;++t) jc[t]=MOD(jc[t-1],t),invc[t]=MOD(invc[mod%t],mod-mod/t),inv[t]=MOD(inv[t-1],invc[t]);
    }
    
    int c(const int&n,const int&m){return n<m||m<0?0:MOD(jc[n],MOD(inv[n-m],inv[m]));}
    int cat(int n){return MOD(c(2*n,n),invc[n+1]);}
    
    int main(){
    	pre(1e4+5);
    	int n=qr(),k=qr();
    	dp[0][0]=1; mi[0]=1;
    	for(int t=1;t<=n+5;++t) mi[t]=MOD(mi[t-1],invc[n]);
    	for(int t=1;t<=k;++t){
    		for(int i=n;i;--i) temp[i]=MOD(MOD({dp[t-1][i],jc[i],mi[i+2]})+temp[i+1]);
    		for(int i=1,g=n;i<=n;++i,g=MOD(g,n)){
    			int ret=0;			
    			ret=MOD(ret+MOD({dp[t-1][i-1],n-i+1,invc[n]}));
    			ret=MOD(ret+MOD({temp[i],n-i+1,g,inv[i-1]}));
    			dp[t][i]=ret;
    		}
    	}
    	int ans=0;
    	for(int t=0;t<=n;++t){
    		int ret=0;
    		for(int j=0;j<=n/2-1;++j){
    			int sav=MOD({cat(j),n-2*j-1,c(n-2*j-2,t-1-j)});
    			ret=MOD(ret+sav);
    		}
    		ans=MOD(ans+MOD({inv[n],jc[t],jc[n-t],dp[k][t],ret,2}));
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
    

    P6690 一次函数

    你觉得我会?

  • 相关阅读:
    golang手动导入github net(https://github.com/golang/net)库到本地(Windows)使用
    lstm例子generate_movies函数分析
    python使用pylab一幅图片画多个图
    python数组array的transpose方法
    python Parallel delayed 示例
    json&pickle数据序列化模块
    html的标签分类————body内标签系列
    html的标签分类————可以上传的数据篇
    不可将布尔值直接与true或者1进行比较
    mock
  • 原文地址:https://www.cnblogs.com/winlere/p/13378564.html
Copyright © 2020-2023  润新知