zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Advanced Configuration Tricks
    Reviewing the Blog Module
    Editing and Deleting Data
    Making Use of Forms and Fieldsets
    Understanding the Router
    SQL Abstraction and Object Hydration
    Preparing for Different Databases
    Java学习理解路线图
    Openstack学习历程_1_视频
    CentOS安装Nginx负载
  • 原文地址:https://www.cnblogs.com/tyqtyq/p/11818899.html
Copyright © 2011-2022 走看看