• Educational Codeforces Round 10


    EDU10,C,D,E,典中典。

    A. Gabriel and Caterpillar

    思路:硬模拟即可。

    #include 
    
    using namespace std;
    const int N = 2e6 + 5;
    typedef long long ll;
    typedef pair<ll, ll> pll;
    typedef array<ll, 3> p3;
    int mod = 998244353;
    const int maxv = 4e6 + 5;
    // #define endl "\n"
    
    void solve()
    {	
    	int h1,h2;
    	cin>>h1>>h2;
    	int a,b;
    	cin>>a>>b;
    	if(h1+8*a>=h2){
    		cout<<0<<endl;
    		return ;
    	}
    	int day=1;
    	int x;
    	if(a<=b){
    		cout<<-1<<endl;
    		return ;
    	}
    	h1+=8*a-12*b;
    	if(h1+a*12>=h2){
    		cout<<day<<endl;
    		return ;
    	}
    	x=h2-h1-a*12;
    	cout<<day+(x+(a-b)*12-1)/((a-b)*12)<<endl;
    }
    
    int main()
    {
        ios::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	int t;
    	t=1;
    	//cin>>t;
    	while(t--){
    		solve();
    	}
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    B. z-sort

    思路:排序后奇偶对调即可,不存在不合法的情况。

    #include 
    
    using namespace std;
    const int N = 2e6 + 5;
    typedef long long ll;
    typedef pair<ll, ll> pll;
    typedef array<ll, 3> p3;
    int mod = 998244353;
    const int maxv = 4e6 + 5;
    // #define endl "\n"
    
    void solve()
    {	
    	int n;
    	cin>>n;
    	vector<int> a(n+5);
    	for(int i=1;i<=n;i++) cin>>a[i];
    	sort(a.begin()+1,a.begin()+1+n);
    	for(int i=2;i+1<=n;i+=2){
    		swap(a[i],a[i+1]);
    	}
    	int f=1;
    	for(int i=1;i<=n;i++){
    		cout<<a[i]<<" ";
    	}
    	cout<<endl;
    }
    
    int main()
    {
        ios::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	int t;
    	t=1;
    	//cin>>t;
    	while(t--){
    		solve();
    	}
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    C. Foe Pairs

    很经典的一道计算贡献的题目。
    对于计算贡献区间的题目,我们一般有两种处理方法:
    第一种就是固定左端点,去枚举右端点;
    第二种就是考虑对于二进制类型的贡献问题,我们将每个数字进行拆位,考虑该数二进制表示下每一位的贡献。

    思路:很显然,因为要考虑所有区间对答案的贡献,所以我们思考,对于每一个左端点,是否能求出其能延申的最远距离,即最大合法右端点,我们对限制条件进行处理,即对于给定数对 [ a , b ] [a,b] [a,b], a a a所在的下标 i i i是无法延申到 b b b所在的下标 j j j的,最后按此维护一下最大后缀即可,因为我们顺着来无法退出第 i i i个数最远能够延申到哪,因为只有第 i + 1 i+1 i+1个数确定了其延申范围,我们才能对 i i i进行更新。(因为不会出现第 i + 1 i+1 i+1能到达 j j j,但 i i i无法到达 j j j的情况)。

    #include 
    
    using namespace std;
    const int N = 2e6 + 5;
    typedef long long ll;
    typedef pair<ll, ll> pll;
    typedef array<ll, 3> p3;
    int mod = 998244353;
    const int maxv = 4e6 + 5;
    // #define endl "\n"
    
    void solve()
    {	
    	int n,m;
    	cin>>n>>m;
    	vector<int> a(n+5),st(n+5);
    	for(int i=1;i<=n;i++) cin>>a[i],st[a[i]]=i;
    	vector<int> l(n+5,n),r(n+5);
    	for(int i=1;i<=m;i++){
    		int x,y;
    		cin>>x>>y;
    		int xi=st[x],yi=st[y];
    		if(xi>yi) swap(xi,yi);
    		l[xi]=min(l[xi],yi-1);
    	}
    	l[n+1]=n+1;
    	for(int i=n-1;i>=1;i--){ 
    		l[i]=min(l[i+1],l[i]);
    	}
    	ll sum=0;
    	for(int i=1;i<=n;i++){
    		ll x=l[i]-i+1;
    		sum+=x;
    	}
    	cout<<sum<<endl;
    }
    
    int main()
    {
        ios::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	int t;
    	t=1;
    	//cin>>t;
    	while(t--){
    		solve();
    	}
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    D. Nested Segments

    又是典中典,经典二维偏序问题,对于给定线段 [ l , r ] [l,r] [l,r],我们要找到在 [ l , r ] [l,r] [l,r]范围内的线段数,那么可以将 l , r l,r l,r转化为二维坐标系中的一个点,然后我们对所有点按照x轴进行排序,此题就转化为了,对于给定的点 ( l , r ) (l,r) (l,r),横坐标比他大,但纵坐标比他小的点有多少个,又因为我们是对横坐标进行排序,那么我们限制我们只需要从横坐标最大的点开始,使用一个数据结构去维护,对于每个点,有多少个点的纵坐标自身小即可。每遍历完一个点,我们就将该点放入数据结构中即可。
    上述过程,我们很容易想到使用树状数组即可对上述内容进行维护。
    注意该题数据范围为1e9,所以需要先进行离散化。

    #include 
    
    using namespace std;
    const int N = 2e6 + 5;
    typedef long long ll;
    typedef pair<ll, ll> pll;
    typedef array<ll, 3> p3;
    int mod = 998244353;
    const int maxv = 4e6 + 5;
    // #define endl "\n"
    
    struct MIT//树状数组
    {
    ll tr[N];
    int lowbit(int x) {
        return x & (-x);
    }
    
    void add(int u, int v) {
        for (int i = u; i < N; i += lowbit(i)) {
            tr[i] += v;
        }
    }
    
    ll query(int x) {
        ll res = 0;
    
        for (int i = x; i > 0; i -= lowbit(i)) {
            res += tr[i];
        }
    
        return res;
    }
    };
    MIT c;
    void solve()
    {	
    
    	int n;
    	cin>>n;
    	vector<p3> se(n+5);
    	for(int i=1;i<=n;i++){
    		int l,r;
    		cin>>l>>r;
    		se[i]={l,r,i};//因为要进行离散化,所以需要储存编号
    	}
    	sort(se.begin()+1,se.begin()+1+n,[](p3 x,p3 y){
    		return x[0]>y[0];
    	});
    	vector<int> g(n+5);
    	for(int i=1;i<=n;i++){
    		auto [x,y,z]=se[i];
    		g[i]=y;
    	}
    	sort(g.begin()+1,g.begin()+1+n);
    	for(int i=1;i<=n;i++){
    		int t=lower_bound(g.begin()+1,g.begin()+1+n,se[i][1])-g.begin();//经典离散化操作
    		se[i][1]=t;//第二维才是我们需要的值
    	}
    	vector<int> ans(n+5);
    	for(int i=1;i<=n;i++){//对每个点进行遍历
    		auto [x,y,z]=se[i];
    		int res=c.query(y);
    		ans[z]=res;
    		c.add(y,1);
    	}
    	for(int i=1;i<=n;i++) cout<<ans[i]<<endl;
    }
    
    int main()
    {
        ios::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	int t;
    	t=1;
    	//cin>>t;
    	while(t--){
    		solve();
    	}
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    E. Pursuit For Artifacts

    还是典中典。
    很明显的无向图,要求一条路只能通过一遍,标准的缩点提示。
    思路:缩点后看从 a − b a-b ab的路径上是否存在边权为 1 的边即可。

    #include 
    
    using namespace std;
    const int N = 2e6 + 5;
    typedef long long ll;
    typedef pair<ll, ll> pll;
    typedef array<ll, 3> p3;
    int mod = 1e9+7;
    const int maxv = 4e6 + 5;
    // #define endl "\n"
    
    int n,m;
    struct node
    {
    	int a,b,w;
    }z[N];
    
    vector<pll> e[N];
    vector<pll> e2[N];
    vector<vector<int> > vdcc;
    int dfsn[N],low[N],tot,b[N];
    stack<int> s;
    void add(int u,int v,int i)
    {
    	e[u].push_back({v,i});
    	e[v].push_back({u,i});
    }
    
    void tarjan(int x,int f)//tarjan缩点,跑出来所有的边双连通分量
    {
    	dfsn[x]=low[x]=++tot,s.push(x);
    	for(auto [u,i]: e[x]){
    		if(!dfsn[u]){
    			tarjan(u,i);
    			low[x]=min(low[x],low[u]);
    		}
    		else if(f!=i) low[x]=min(low[x],dfsn[u]);
    	}
    	if(dfsn[x]==low[x]){
    		vector<int> c;
    		while(1){
    			auto t=s.top();
    			b[t]=vdcc.size();
    			c.push_back(t);
    			s.pop();
    			if(t==x) break;
    		}
    		vdcc.push_back(c);
    	}
    }
    int st,ed;
    int val[N];
    int ans;
    void dfs(int x,int f,int ans)//记录ans,
    {
    	if(x==ed){
    		if(ans){
    			cout<<"YES"<<endl;
    		}
    		else cout<<"NO"<<endl;
    		return ;
    	}
    	for(auto [u,w]: e2[x]){
    		if(u!=f) dfs(u,x,ans|w|val[u]);
    	}
    }
    
    
    void solve()
    {	
    	cin>>n>>m;
    	for(int i=1;i<=m;i++){
    		int u,v,w;
    		cin>>u>>v>>w;
    		add(u,v,i);
    		z[i]={u,v,w};
    	}
    	cin>>st>>ed;
    	for(int i=1;i<=n;i++){
    		if(!dfsn[i]){
    			tarjan(i,-1);
    		}
    	}
    	for(int i=1;i<=m;i++){//缩点过程
    		auto [u,v,w]=z[i];
    		if(b[u]!=b[v]){
    			e2[b[u]].push_back({b[v],w});
    			e2[b[v]].push_back({b[u],w});
    		}
    		else{//如果当前点在一个连通分量里面,我们就把当前连通分量和w与一下,因为如果当前权值为1,整个连通分量又可以相互到达,所以该连通分量的权值就为1.
    			val[b[u]]|=w;
    		}
    	}
    	st=b[st],ed=b[ed];
    	ans=val[st];
    	dfs(st,-1,ans);
    }
    
    int main()
    {
        ios::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	int t;
    	t=1;
    	//cin>>t;
    	while(t--){
    		solve();
    	}
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
  • 相关阅读:
    Qt中的UI文件介绍
    【工程化系列】汇编代码中无法链接的外部符号的几个原因分析
    期末前端web大作业——我的家乡陕西介绍网页制作源码HTML+CSS+JavaScript
    mybatis 15: 缓存
    Redis 中 Set 数据结构详解
    全面进化!Apache Doris 1.2.0 Release 版本正式发布|版本通告
    nvm详解(mac环境nvm安装步骤及踩坑问题)
    npm包、全局数据共享、分包
    计算机毕设(附源码)JAVA-SSM基于驾校管理系统
    一步一步教你如何在Windows 10上使用Java,包括下载、安装和配置等
  • 原文地址:https://blog.csdn.net/Unlimited_ci/article/details/133842956