• #796 Div.2 F. Sanae and Giant Robot set *


    1688F
    set,2500

    题意

    给出 a , b a,b a,b 两个序列,并给出 m m m 个区间 [ l i , r i ] [l_i,r_i] [li,ri],每次可以从它们中满足 ∑ i = l r a i = ∑ i = l r b i \sum_{i=l}^ra_i=\sum_{i=l}^rb_i i=lrai=i=lrbi 的区间中任选一个,对这个区间的所有数执行 a i = b i a_i=b_i ai=bi,问能否经过若干次操作,使得 a a a 序列和 b b b 序列相同?

    思路

    区间可以被选当且仅当这个区间内两序列和相同,也就是差为0,所以用数组 s i s_i si 表示两个数组前缀和之差,即 s i = s i − 1 + a i − b i s_i=s_{i-1} + a_i - b_i si=si1+aibi,则区间 [ l , r ] [l,r] [l,r] 可以被选当且仅当 s l − 1 = s r s_{l-1}=s_r sl1=sr,且操作过后 s l − 1 = s l = . . . = s r s_{l-1}=s_l=...=s_r sl1=sl=...=sr,最终目标是令 s s s 数组全为 0 0 0 ,因此选 s l − 1 ≠ 0 s_{l-1}\neq 0 sl1=0 的没有意义。

    所以题可以转化为:对于区间 [ l , r ] [l,r] [l,r] ,如果 s l − 1 = s r = 0 s_{l-1}=s_{r}=0 sl1=sr=0 ,则使 s l − 1 = s l = . . . = s r = 0 s_{l-1}=s_l=...=s_r=0 sl1=sl=...=sr=0 , 是否可以使 s s s 全为 0 0 0

    可以用 queue 存数组 s s s 已经为0的位置,set 存还不是0的位置,依次遍历已经为0的位置所连的边,若另一点也为0,则遍历范围在这个区间内的 set 中元素并加入队列。如果最终队空但 set 未空,则无解。每个点至多加入队列一次,时间复杂度 O ( ( n + m ) log ⁡ n ) O((n+m)\log n) O((n+m)logn)

    代码

    int n, m;
    int a[maxn], b[maxn], s[maxn];
    vector<int> e[maxn];
    void solve() {
        cin >> n >> m;
        set<int> se;
        for(int i = 1; i <= n; i++) {
        	cin >> a[i];
        	se.insert(i);
        }
        for(int i = 1; i <= n; i++) {
        	cin >> b[i];
        	s[i] = s[i-1] + a[i] - b[i];
        	e[i].clear();
        }
        e[0].clear();
        //se 表示非0的位置
        for(int i = 1; i <= m; i++) {
        	int x, y;
        	cin >> x >> y;
        	x--;
        	e[x].pb(y);
        	e[y].pb(x);
        }
        queue<int> q;
        for(int i = 0; i <= n; i++) {
        	if(!s[i]) {
        		q.push(i);
        		se.erase(i);
        	}
        }
        while(!q.empty()) {
        	int x = q.front();
        	q.pop();
        	for(int i = 0; i < e[x].size(); i++) {
        		int y = e[x][i];
        		if(s[y]) continue;
        		int l = min(x, y), r = max(x, y);
        		auto itl = se.lower_bound(l), itr = se.upper_bound(r);
        		for(auto it = itl; it != itr; it++) {
        			s[*it] = 0;
        			q.push(*it);
        		}
        		se.erase(itl, itr);
        	}
        }
        if(!se.empty()) {
        	cout << "NO\n";
        }
        else {
        	cout << "YES\n";
        }
    }
    
    • 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
  • 相关阅读:
    ABAP语法基础2
    TikTok与心灵成长:娱乐与启发并重
    【计算机毕业设计】基于SpringBoot+Vue贵州旅游系统的设计与实现
    HashMap的put方法的源码分析(Java)
    如何做一个知识博主? 善用互联网检索
    uniApp常见面试题-附详细答案
    (八)CSharp-泛型类和参数约束(1)
    【高并发优化手段】基于Springboot项目
    【检索资讯】2022年控制理论与应用国际会议(ICOCAT 2022)已成功被EI检索
    Redis存储结构之zskiplist
  • 原文地址:https://blog.csdn.net/m0_59273843/article/details/125487127