• JZOJ-2019-11-7 A组


    T1

    Input

    从文件 awesome.in 中读入数据。
    第一行 2 个用空格隔开的整数 (n), (P)
    第二行 n 个用空格隔开的整数 (A_1, cdots , A_n)

    Output

    输出到文件 awesome.out 中。
    输出一行一个整数,表示极好的三元组的数目。

    前置知识

    1. 字符串
    2. 暴力
    3. STL map

    解法

    考虑若(x=y ot= z), 则直接暴力求出z的个数即可

    (x=y=z), 暴力扫描序列判断即可

    否则(x ot= y ot= z)去重, 对每个数求出逆元后暴力匹配jike

    代码

    /*code by tyqtyq*/
    #include<bits/stdc++.h>
    #define int long long
    #define f(i,x,y) for(register int i=x, i##end=y; i<=i##end; ++i)
    #define d(i,x,y) for(register int i=y, i##end=x; i>=i##end; --i)
    #define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
    using namespace std;
    int read(int& x){x=0; int f=1, ch=getchar(); while(!isdigit(ch)) f=ch=='-'?-1:f, ch=getchar(); while(isdigit(ch)) x=x*10+ch-'0', ch=getchar(); return x*=f;}
    int read(){int x=0, f=1, ch=getchar(); while(!isdigit(ch)) f=ch=='-'?-1:f, ch=getchar(); while(isdigit(ch)) x=x*10+ch-'0', ch=getchar(); return x*f;}
    int max(int x, int y){return x>y?x:y;} int min(int x, int y){return x<y?x:y;}
    int a[2500], b[2500], inv[2500], n, p, ans=0, ct=0, fa=0;
    map<int, int> mp;
    int power(int a, int b){int res=1, car=a;while(b){if(b&1) res=res*car%p;car=car*car%p;b>>=1;}return res;}
    signed main(){
    	FO(awesome);
    	read(n); read(p);
    	f(i,1,n) read(a[i]);
    	sort(a+1, a+n+1);
    	f(i,1,n) b[i]=a[i];
    	int m=unique(b+1, b+n+1)-b-1;
    	int x=a[n+1]=-1, cnt=0;
    	f(i,1,n+1){
    		if(x!=a[i]){
    			if(cnt>=2){for(int j=1;j<=m;++j){ if(b[j]==x) continue; if((long long)x*x%p*b[j]%p==1) ++ans; }}
    			if(cnt>=3 && ((long long)x*x%p*x%p==1)) ++ans;
    			x=a[i]+(cnt=0);
    		}
    		++cnt;
    	} fa=ans, ans=0;
    	f(i,1,m){
    		if(b[i]%p){
    			inv[i] = power(b[i]%p, p-2);
    			++mp[inv[i]];
    		}
    	}
    	f(i,1,m){
    		if(b[i]%p){
    			--mp[inv[i]];
    			f(j,i+1,m){
    				if(b[j]%p){
    					int x = (long long)b[i]*b[j] % p;
    					auto it=mp.find(x); if(it!=mp.end()) ans += (*it).second;
    					if(x == inv[j]) --ans;
    				}
    			}
    		}
    	}
    	cout<<fa+ans/2<<endl;
    	return 0; //拜拜程序~ 
    }
    

    T2

    Input

    从文件 bag.in 中读入数据。
    单个测试点中包含多组数据,输入第一行为一个非负整数 (T),描述数据组数。接下来依次描述每组数据,对于每组数据:
    第一行一个非负整数 (n),描述物品数量。
    (2) 行至第 (n + 1) 行,每行两个用空格隔开的正整数,其中第 (i + 1) 行的两个数依次为 (w_i, v_i),分别描述第 (i) 个物品的重量和价值。
    接下来一行一个非负整数 (m),描述背包数量。
    接下来一行 (m) 个用空格隔开的正整数 (t_1, cdots , t_m),依次描述各背包的承重上限。

    Output

    输出到文件 bag.out 中。
    一行一个整数,表示能够选出的物品数量的最大值。

    解法

    本题与传统的二维偏序问题类似,只需要仔细考虑维度、顺序问题。

    对于一条长度为(l)的链,贪心地,我们发现用容量最大的(l)个背包一定是最优的背包安排。

    因此将所有点按(x)降序排序,并依次枚举所有点,用权值树状数组维护离散化后每个(y)坐标结尾的最长链长度,注意需要维护能够存的下当前点背包数量,并在更新树状数组时将更新的答案与这个值取(min)

    代码

    #include<bits/stdc++.h>
    using namespace std; /*Copyright [tyqtyq](http://oiertyq.github.io). All rights served.*/
    #define f(i,x,y) for(int i=x,i##end=y;i<=i##end;++i)
    #define d(i,x,y) for(int i=x,i##end=y;i>=i##end;--i)
    #define ri register int
    #define ll long long
    #define il inline
    #define _ 100005
    #define lowbit(x) (x) & (-x)
    namespace intio{char ch; int read(){ ri x=0,f=1; while(!isdigit((ch=getchar()))) f=ch=='-'?-1:1; while(isdigit(ch)) x=x*10+ch-'0', ch=getchar(); return x*f; } int read(int& x) {return x = read();}}; using namespace intio;
    int max(int x, int y) {return x>y?x:y;} int min(int x, int y) {return x<y?x:y;}
    int t[_], n, m, c[_], r[_], rn;
    struct thing{int w, v; thing(int a=0, int b=0):w(a), v(b){}}a[_];
    int cmp1(thing a, thing b){return a.w > b.w || (a.w==b.w && a.v > b.v) ;}
    int cmp2(int a, int b){return a>b;}
    int query(int x){
    	int res=0;
    	while(x<=rn){
    		res = max(res, c[x]);
    		x += lowbit(x);
    	}
    	return res;
    }
    void modify(int p, int x){
    	while(p>0) {
    		c[p] = max(x, c[p]);
    		p -= lowbit(p); 
    	}	
    }
    int T=0;
    int main(){
    	freopen("bag.in", "rb", stdin);
    	freopen("bag.out", "wb", stdout);
    	read(T);
    	while(T--){
    		memset(c, 0, sizeof(c)); 
    		read(n); f(i,1,n) read(a[i].w), r[i]=read(a[i].v);
    		read(m); f(i,1,m) read(t[i]);
    		sort(t+1, t+1+m, cmp2);
    		sort(a+1, a+1+n, cmp1);
    		sort(r+1, r+1+n);
    		rn = unique(r+1, r+1+n) - r - 1;
    		f(i,1,n) a[i].v = lower_bound(r+1, r+1+rn, a[i].v)-r; 
    		int j=0; f(i,1,n){
    			while(j < m && a[i].w <= t[j + 1]) ++j;
    			modify(a[i].v, min(query(a[i].v) + 1,j));
    		}
    		cout<<query(1)<<endl;
    	}
    	return 0;
    }
    

    T3

    Input

    Output

    输出到文件 subtree.out 中。
    输出用单个空格隔开的 (R - L + 1) 个整数,依次表示深度为 (L, L + 1, cdots , R) 的好的(Yazid)树数目对 (998244353) 取模的结果。

    解法

    (dp[i][d])表示(i)个节点深度不超过(d)的有根树数目(很显然,若计算出所有(dp[i][d]),则可以通过差分求得各答案)。若不考虑禁手,则可以枚举根为编号次大子树大小(j),并进行转移,具体转移方程为:

    [dp[i][d]= egin{align*} egin{cases} 0& ext{i为禁手}\ sum_{j=1}^{i-1} dp[i-j][d] imes dp[j][d-1] imes dbinom{i-2}{j-1}& ext{otherwise;} end{cases} end{align*} ]

    代码

    #include<bits/stdc++.h>
    using namespace std; /*Copyright [tyqtyq](http://oiertyq.github.io). All rights served.*/
    #define f(i,x,y) for(int i=x,i##end=y;i<=i##end;++i)
    #define d(i,x,y) for(int i=x,i##end=y;i>=i##end;--i)
    #define ri register int
    #define ll long long
    #define il inline
    #define int unsigned long long
    #define read(X) cin>>X
    const int mod=998244353;
    int max(int x, int y) {return x>y?x:y;} int min(int x, int y) {return x<y?x:y;}
    int dp[505][505], t[505][505], frac[505], inv[505], k;
    int power(int a, int b){
    	int res=1, car=a;
    	while(b){
    		if(b&1) res = (res*car)%mod;
    		car = (car*car)%mod;
    		b>>=1;
    	}
    	return res;
    }
    void init(){
    	frac[0]=inv[0]=1;
    	f(i,1,500) frac[i] = (frac[i-1]*i)%mod;
    	inv[500] = power(frac[500], mod-2);
    	d(i,499,1) inv[i] = (inv[i+1]*(i+1))%mod;
    }
    int n, l, r, d, a[505], u[505];
    int C(int n, int k){
    	return (((frac[n]*inv[k])%mod)*inv[n-k])%mod; 
    }
    signed main(){
    	freopen("subtree.in", "r", stdin); freopen("subtree.out", "w", stdout);
    	int ttt=0;
    	init(); read(n); read(k); f(i,1,k) cin>>ttt, u[ttt]=1; read(l); read(r);
    	if(u[1]) {f(i,l,r) printf("0 "); return puts(""), 0;}
    	f(i,1,n) dp[1][i]=1; f(i,2,n) dp[2][i]=1;
    	f(i,3,n) f(d,1,n) f(j,1,i-1)
    		if(!u[j]) dp[i][d] = ((dp[i][d] + ((((dp[i-j][d]*dp[j][d-1])%mod)*C(i-2, j-1))%mod))%mod);
    	f(i,l,r) cout<<(!u[n] ? ((dp[n][i] - dp[n][i - 1] + mod) % mod) : 0)<<" "; puts("");
    	return 0;
    }
    
  • 相关阅读:
    navicat连接腾讯云服务器mysql
    腾讯云服务器部署1
    域名的注册使用
    python入门1-3章节
    轮播图的实现
    前端起步
    redis部署到云服务器上的一些坑
    面向对象第三单元总结
    面向对象课程第二单元总结
    面向对象课程第一单元总结
  • 原文地址:https://www.cnblogs.com/tyqtyq/p/11818899.html
Copyright © 2020-2023  润新知