zoukankan      html  css  js  c++  java
  • ZR 2020普转提七连测day4

    A

    我们考虑序列的最后一个数字 (x),那么 (>x) 的数字在排名中就没有贡献了,所以我们只能让前面 (<x) 的数尽量靠前。贪心的想我们肯定让这个 (x) 尽量大,也就是说如果把越大的数放在后面,那么就会有更多小的数在前面。

    于是答案等价于求反过来的最大字典序。

    #include <bits/stdc++.h>
    
    #define fi first
    #define se second
    #define db double
    #define U unsigned
    #define P std::pair<int,int>
    #define LL long long
    #define pb push_back
    #define MP std::make_pair
    #define all(x) x.begin(),x.end()
    #define CLR(i,a) memset(i,a,sizeof(i))
    #define FOR(i,a,b) for(int i = a;i <= b;++i)
    #define ROF(i,a,b) for(int i = a;i >= b;--i)
    #define DEBUG(x) std::cerr << #x << '=' << x << std::endl
    
    const int MAXN = 1e5 +5;
    
    std::vector<int> G[MAXN];
    int deg[MAXN];
    int n,m;
    
    inline void Solve(){
    	scanf("%d%d",&n,&m);
    	FOR(i,1,n) G[i].clear();
    	FOR(i,1,n) deg[i] = 0;
    	FOR(i,1,m){
    		int u,v;scanf("%d%d",&u,&v);
    		G[v].pb(u);++deg[u];
    	}
    	std::priority_queue<int> q;
    	FOR(i,1,n) if(!deg[i]) q.push(i); 
    	std::vector<int> ans;
    	while(!q.empty()){
    		int v = q.top();q.pop();ans.pb(v);
    		for(auto x:G[v]){
    			if(!--deg[x]){
    				q.push(x);
    			}
    		}
    	}
    	std::reverse(all(ans));
    	if(ans.size() != n) puts("Impossible!");
    	else{
    		for(auto x:ans) printf("%d ",x);
    		puts("");
    	}
    }
    
    int main(){
    	int T;scanf("%d",&T);
    	while(T--) Solve();
    	return 0;
    }
    

    B

    暴力做法是枚举两位后在哈希表里查一下,复杂度 (O(nlog^2 a_i))

    注意到我们可以分开枚举,枚举 (a) 的某一位,将对应的数插入到哈希表,然后枚举 (b) 的某一位查询,注意要减掉多算的,复杂度 (O(n log a_i))。注意这样会把 (a_i=b_i) 多算 (log a_i) 次,特判一下就行。

    #include <bits/stdc++.h>
    
    #define fi first
    #define se second
    #define db double
    #define U unsigned
    #define P std::pair<LL,LL>
    #define LL long long
    #define pb push_back
    #define MP std::make_pair
    #define all(x) x.begin(),x.end()
    #define CLR(i,a) memset(i,a,sizeof(i))
    #define FOR(i,a,b) for(int i = a;i <= b;++i)
    #define ROF(i,a,b) for(int i = a;i >= b;--i)
    #define DEBUG(x) std::cerr << #x << '=' << x << std::endl
    
    const int MAXN = 1e5 + 5;
    int n,m,a[MAXN],b[MAXN];
    const int mod = 19260817;
    std::mt19937 g(time(NULL));
    int BASE;
    
    inline char nc(){
        #define SIZE 1000000+3
        static char buf[SIZE],*p1 = buf+SIZE,*p2 = buf+SIZE;
        if(p1 == p2){
            p1 = buf;p2 = buf+fread(buf,1,SIZE,stdin);
            if(p1 == p2) return -1;
        }
        return *p1++;
        #undef SIZE
    }
    
    template <typename T>
    inline void read(T &x){
        x = 0;int flag = 0;char ch = nc();
        while(!isdigit(ch)){
            if(ch == '-') flag = 1;
            ch = nc();
        }
        while(isdigit(ch)){
            x = (x<<1) + (x<<3) + (ch^'0');
            ch = nc();
        }
        if(flag) x = -x;
    }
    
    struct HASH{
    	struct Edge{
    		int val,cnt,nxt;
    	}e[MAXN];
    	int head[mod],cnt = 0;
    	
    	inline void insert(int x){
    		x ^= BASE;
    		int b = x%mod;
    		for(int i = head[b];i;i = e[i].nxt){
    			if(e[i].val == x){
    				e[i].cnt++;
    				return;
    			}
    		}
    		e[++cnt] = (Edge){x,1,head[b]};head[b] = cnt;
    	}
    	
    	inline int find(int x){
    		x ^= BASE;
    		int b = x%mod;
    		for(int i = head[b];i;i = e[i].nxt){
    			if(e[i].val == x) return e[i].cnt;
    		}
    		return 0;
    	}
    }S;
    
    int main(){
    	BASE = g()%((1<<30));
    	read(n);read(m);
    	FOR(i,1,n){
    		int x;read(x);S.insert(x);
    	}
    	LL ans = 0;
    	FOR(i,1,m){
    		int x;read(x);
    		FOR(a,0,29){
    			FOR(b,a+1,29){
    				ans += S.find(x^(1<<a)^(1<<b));
    			}
    		}
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    C

    [post cid="1399" /]
    这场CF的 E

    #include <bits/stdc++.h>
    
    #define fi first
    #define se second
    #define db double
    #define U unsigned
    #define P std::pair<int,int>
    #define LL long long
    #define pb push_back
    #define MP std::make_pair
    #define all(x) x.begin(),x.end()
    #define CLR(i,a) memset(i,a,sizeof(i))
    #define FOR(i,a,b) for(int i = a;i <= b;++i)
    #define ROF(i,a,b) for(int i = a;i >= b;--i)
    #define DEBUG(x) std::cerr << #x << '=' << x << std::endl
    
    const int MAXN = 5e5 + 5;
    const int ha = 1e9 + 7;
    int k,n,m;
    P a[2][MAXN];
    std::vector<int> S;
    int lim[2][MAXN];
    int f[2][MAXN];
    // 当前这一位是0/1 上一个不一样的在哪里 
    
    inline void add(int &x,int y){
    	x += y;if(x >= ha) x -= ha;
    }
    
    inline int qpow(int a,int n=ha-2){
    	int res = 1;
    	while(n){
    		if(n & 1) res = 1ll*res*a%ha;
    		a = 1ll*a*a%ha;
    		n >>= 1;
    	}
    	return res;
    }
    
    int main(){
    	scanf("%d%d%d",&k,&n,&m);
    	S.pb(0);S.pb(k);
    	FOR(i,1,n){
    		scanf("%d%d",&a[0][i].fi,&a[0][i].se);--a[0][i].fi;
    		S.pb(a[0][i].fi);S.pb(a[0][i].se);
    	}
    	FOR(i,1,m){
    		scanf("%d%d",&a[1][i].fi,&a[1][i].se);--a[1][i].fi;
    		S.pb(a[1][i].fi);S.pb(a[1][i].se);
    	}
    	CLR(lim,-1);
    	std::sort(all(S));S.erase(std::unique(all(S)),S.end());
    	FOR(i,1,n){
    		a[0][i].fi = std::lower_bound(all(S),a[0][i].fi)-S.begin();
    		a[0][i].se = std::lower_bound(all(S),a[0][i].se)-S.begin();
    		lim[0][a[0][i].se] = std::max(lim[0][a[0][i].se],a[0][i].fi);
    	}
    	FOR(i,1,m){
    		a[1][i].fi = std::lower_bound(all(S),a[1][i].fi)-S.begin();
    		a[1][i].se = std::lower_bound(all(S),a[1][i].se)-S.begin();
    		lim[1][a[1][i].se] = std::max(lim[1][a[1][i].se],a[1][i].fi);
    	}
    	int n = S.size();
    	FOR(i,0,1) FOR(j,1,n) lim[i][j] = std::max(lim[i][j],lim[i][j-1]);
    	f[0][0] = 1;int sm0 = 1,tp0 = 0,sm1 = 0,tp1 = 0;
    	FOR(i,0,n-2){
    		while(tp0 <= lim[1][i]) add(sm0,ha-f[0][tp0]),++tp0;
    		while(tp1 <= lim[0][i]) add(sm1,ha-f[1][tp1]),++tp1;
    		add(f[1][i],sm0);add(f[0][i],sm1);
    		int gx = qpow(2,S[i+1]-S[i]-1);add(gx,ha-1);
    		gx = 1ll*gx*(sm0+sm1)%ha;
    		add(f[0][i+1],gx);add(f[1][i+1],gx);
    		int t0 = sm0,t1 = sm1;
    		add(sm0,t1);add(sm1,t0);
    		add(sm0,gx);add(sm1,gx);
    	}
    	int ans = 0;
    	FOR(i,0,n) if(i > lim[1][n]) add(ans,f[0][i]);
    	FOR(i,0,n) if(i > lim[0][n]) add(ans,f[1][i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    D

    考虑这个条件等价于第 (i) 个位置可以有一个容量是 ([a_i,b_i]) 的物品,要求凑出 (p) 的最小代价。

    于是单调队列优化 dp 即可。

    #include <bits/stdc++.h>
    
    #define fi first
    #define se second
    #define db double
    #define U unsigned
    #define P std::pair<int,int>
    #define LL long long
    #define pb push_back
    #define MP std::make_pair
    #define all(x) x.begin(),x.end()
    #define CLR(i,a) memset(i,a,sizeof(i))
    #define FOR(i,a,b) for(int i = a;i <= b;++i)
    #define ROF(i,a,b) for(int i = a;i >= b;--i)
    #define DEBUG(x) std::cerr << #x << '=' << x << std::endl
    
    const int MAXN = 1000+5;
    int n,a[MAXN],b[MAXN],c[MAXN],p;
    LL f[2][10005];
    int now;
    
    inline void Solve(){
    	scanf("%d%d",&n,&p);
    	FOR(i,1,n) scanf("%d",a+i);
    	FOR(i,1,n) scanf("%d",b+i);
    	FOR(i,1,n) scanf("%d",c+i);
    	now = 0;CLR(f[now],0x3f);
    	f[now][0] = 0;
    	FOR(i,1,n){
    		CLR(f[now^1],0x3f);
    		std::deque<int> q;
    		FOR(j,0,p){
    			if(j-a[i] >= 0){
    				while(!q.empty() && f[now][q.back()] >= f[now][j-a[i]]) q.pop_back();
    				q.pb(j-a[i]);
    			}
    			while(!q.empty() && q.front() < j-b[i]) q.pop_front();
    			if(!q.empty()) f[now^1][j] = f[now][q.front()]+c[i];
    			f[now^1][j] = std::min(f[now^1][j],f[now][j]);
    		}
    		now ^= 1;
    	}
    	f[now][p] > 2e9 ? puts("IMPOSSIBLE!!!") : printf("%lld
    ",f[now][p]);
    }
    
    int main(){
    	int T;scanf("%d",&T);
    	while(T--) Solve();
    	return 0;
    }
    
  • 相关阅读:
    Golang的值类型和引用类型的范围、存储区域、区别
    ubuntu下ssh使用 与 SCP 使用
    ubuntu 搭建svn服务器
    Java中Math类的几个四舍五入方法的区别
    mongoDB 批量更改数据,某个字段值等于另一个字段值
    mongoDB 查询附近的人的语句
    mongodb常用操作语句
    JAVA 根据经纬度算出附近的正方形的四个角的经纬度
    JAVA 计算地球上任意两点(经纬度)距离
    Mongodb数据备份恢复
  • 原文地址:https://www.cnblogs.com/rainair/p/14305498.html
Copyright © 2011-2022 走看看