zoukankan      html  css  js  c++  java
  • Vjudge contest 424925

    Problem A

    发现这一场有一点自闭啊,人均题我都不会。


    将球桌翻折开,然后只要穿过其中的一个角就是进洞了,可以根据这个列出等式之后变成一个用扩展 (gcd) 能解的方程,然后求最小的整数解就可以了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int n,m,x,y,vx,vy;
    bool flagx=false,flagy=false;
    int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
    void exgcd(int a,int b,int &x,int &y){
    	if(b==0) return x=1,y=0,void();
    	exgcd(b,a%b,x,y);
    	int t=x;x=y,y=t-a/b*y;
    }
    signed main(){
    	cin>>n>>m>>x>>y>>vx>>vy;
    	if(vy==0){
    		if(y==0||y==m) printf("%lld %lld
    ",vx>0?n:0,y);
    		else printf("-1
    ");
    		return 0;
    	}
    	if(vx==0){
    		if(x==0||x==n) printf("%lld %lld
    ",x,vy>0?m:0);
    		else printf("-1
    ");
    		return 0;
    	}
    	if(vx<0) vx=-vx,x=n-x,flagx=true;
    	if(vy<0) vy=-vy,y=m-y,flagy=true;
    	int A,B,C=gcd(n,m);
    	if((x-y)%C) return printf("-1"),0;
    	int dA=-m/C,dB=n/C;exgcd(n,m,A,B),B=-B;
    	if(dA<0) dA=-dA,dB=-dB;
    	A*=(x-y)/C,A=(A%dA+dA)%dA;
    	if(!A) A=dA;
    	B=(A*n-(x-y))/m;
    	// printf("%lld %lld
    ",A,B);
    	printf("%lld %lld
    ",((A&1)^flagx)?n:0,((B&1)^flagy)?m:0);
    }
    

    Problem B

    上次好像做过,没做出来,也没订正。


    然后你用 (set) 强行维护一下整个过程,得到每一个点最后的点的个数,然后用并查集来维护一下后面的点侵犯前面的点的情况,就可以了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=3e5+5;
    int n,m;
    struct Cow{int x,y;}a[N];
    bool cmp1(Cow a,Cow b){return a.y>b.y;}
    struct Fence{int x,y,id,fa;}b[N];
    bool cmp2(Fence a,Fence b){return a.y>b.y;}
    struct Point{int x,id;};
    bool operator < (Point a,Point b){return a.x<b.x;}
    set<Point> bag;
    #define It set<Point>::iterator
    int fa[N],cnt[N],res[N];
    struct DSU{
    	int fa[N];
    	void init(int n){for(int i=1;i<=n;++i) fa[i]=i;}
    	int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    	void merge(int u,int v){
    		int fu=find(u),fv=find(v);
    		if(fu!=fv) fa[fv]=fu,cnt[fu]+=cnt[fv];
    	}
    }d;
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;++i) scanf("%d%d",&a[i].x,&a[i].y);
    	cin>>m;
    	for(int i=1;i<=m;++i) scanf("%d%d",&b[i].x,&b[i].y),b[i].id=i;
    	sort(a+1,a+1+n,cmp1),sort(b+1,b+1+m,cmp2);
    	int j=1;
    	for(int i=1;i<=m;++i){
    		It tmp;
    		while(j<=n&&a[j].y>b[i].y){
    			tmp=bag.lower_bound((Point){a[j].x,0});
    			j++;if(tmp!=bag.end()) cnt[tmp->id]++;
    		}
    		tmp=bag.lower_bound((Point){b[i].x,0});
    		if(tmp!=bag.end()) fa[b[i].id]=tmp->id;
    		// printf("fa %d %d
    ",b[i].id,fa[b[i].id]);
    		bag.insert((Point){b[i].x,b[i].id});
    		tmp=bag.find((Point){b[i].x,b[i].id});
    		while(tmp!=bag.begin()){
    			tmp--;
    			if(tmp->id<b[i].id) break;
    			else bag.erase(tmp);
    			tmp=bag.find((Point){b[i].x,b[i].id});
    		}
    	}
    	while(j<=n){
    		It tmp=bag.lower_bound((Point){a[j].x,0});
    		j++;if(tmp!=bag.end()) cnt[tmp->id]++;
    	}
    	d.init(m);
    	for(int i=m;i>=1;--i) res[i]=cnt[d.find(i)],d.merge(i,fa[i]);
    	for(int i=1;i<=m;++i) printf("%d
    ",res[i]);
    	return 0;
    }
    

    Problem E

    大水题,从小到大加入然后用并查集和 ( ext{set}) 乱搞一下就可以了?

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+5;
    int n,res1,res2;
    struct Data{int data,pos;}a[N];
    bool cmp(const Data a,const Data b){return a.data<b.data;}
    struct DSU{
    	int fa[N],size[N];multiset<int> bag;
    	int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    	void merge(int u,int v){
    		int fu=find(u),fv=find(v);
    		if(fu!=fv){
    			bag.erase(bag.find(size[fu]));
    			bag.erase(bag.find(size[fv]));
    			fa[fv]=fu,size[fu]+=size[fv];
    			bag.insert(size[fu]);
    		}
    	}
    }d;
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;++i){
    		scanf("%d",&a[i].data);
    		a[i].pos=i;
    	}
    	sort(a+1,a+1+n,cmp);
    	for(int i=1;i<=n;++i){
    		d.fa[a[i].pos]=a[i].pos;
    		d.size[a[i].pos]=1,d.bag.insert(1);
    		if(a[i].pos>1&&d.fa[a[i].pos-1]) d.merge(a[i].pos,a[i].pos-1);
    		if(a[i].pos<n&&d.fa[a[i].pos+1]) d.merge(a[i].pos,a[i].pos+1);
    		set<int>::iterator tmp1=d.bag.begin(),tmp2=d.bag.end();tmp2--;
    		if(*tmp1==*tmp2){
    			if((int)d.bag.size()>res1)
    			res1=d.bag.size(),res2=a[i].data+1;
    		}
    	}
    	return printf("%d
    ",res2),0;
    }
    
  • 相关阅读:
    数据库系统理论概念
    SQL常用函数
    Android中几种常见的定时刷新方式
    Android Resource介绍和使用
    Android 使用Loader示例
    Android框架浅析之锁屏(Keyguard)机制原理
    Android Power Management
    Android中蓝牙的基本使用
    分组ListView使用技巧
    使用CursorLoader异步加载数据
  • 原文地址:https://www.cnblogs.com/Point-King/p/14524176.html
Copyright © 2011-2022 走看看