3693: 圆桌会议

3693: 圆桌会议

https://www.lydsy.com/JudgeOnline/problem.php?id=3693

分析:

  Hall定理+线段树。

  如果将桌子放到左边,每组的人拆开放到右边,就成了二分图匹配问题,问是否存在完美匹配。

  Hall定理:设二分图中G=<V1,V2,E>中 |V1|=m<=|V2|=n,G中存在从V1到V2的完全匹配当且仅当V1中任意k(k=1,2,...,m)个顶点至少与V2中k个顶点是相邻的。

  但是此题中,判断左边所有的Li,Ri就行了。

  首先如果左边的桌子没有被一些人选到(即没有边),显然不用考虑。然后只去考虑剩下的点的子集复杂度也是2^n级别的。剩下的许多桌子一定是被一些组的人选到了。考虑一组人选到的桌子Li,Ri,那么这些桌子向右边对部分人连的边是相同的(每个桌子都连向这组的每个人),那么只要判一下这个区间是否满足Ri-Li+1>=Σai(连向右边的点的点数)就行了。这个区间的子集就可以不用考虑了,因为每个点连出的边都一样。然后在查一下多个区间和来的情况,就是最小的l,和最大的r之间。

  所以查询的时候只需要查任意的L与任意的R就行了。然后查询就是R-L+1>=s(s为L~R这些点连向右边的点数),R>=s+L-1,然后对于每个Ri查询所有小于Ri的L,是否满足这个式子。线段树维护这个值,每次查询所有小于Li的L的最大值。加入一个Ri,加入一个区间Li~Ri,然后所有的小于Li的L都应更新加上ai,表示L~Ri的向右边连的点数增加了ai。

代码:

扫描二维码关注公众号,回复: 3191946 查看本文章
  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<cctype>
  7 #include<set>
  8 #include<vector>
  9 #include<queue>
 10 #include<map>
 11 #define fi(s) freopen(s,"r",stdin);
 12 #define fo(s) freopen(s,"w",stdout);
 13 using namespace std;
 14 typedef long long LL;
 15 
 16 inline int read() {
 17     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
 18     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
 19 }
 20 
 21 const int N = 200005;
 22 const int M = 400005;
 23 struct Que{
 24     int l,r,v;
 25     Que() {}
 26     Que(int a,int b,int c) { l = a, r = b, v = c; }
 27     bool operator < (const Que &A) const {
 28         return r < A.r;
 29     }
 30 }q[N];
 31 int Num[N << 1];
 32 int mx[M << 2], tag[M << 2];
 33 
 34 #define Root 1, n, 1
 35 #define lson l, mid, rt << 1
 36 #define rson mid + 1, r, rt << 1 | 1
 37 
 38 void pushup(int rt) {
 39     mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
 40 }
 41 void pushdown(int rt) {
 42     if (tag[rt]) {
 43         mx[rt << 1] += tag[rt]; tag[rt << 1] += tag[rt];
 44         mx[rt << 1 | 1] += tag[rt]; tag[rt << 1 | 1] += tag[rt];
 45         tag[rt] = 0;
 46     }
 47 }
 48 void build(int l,int r,int rt) {
 49     tag[rt] = mx[rt] = 0;
 50     if (l == r) {
 51         mx[rt] = Num[l] - 1;
 52         return; 
 53     }
 54     int mid = (l + r) >> 1;
 55     build(lson); build(rson);
 56     pushup(rt);
 57 }
 58 void update(int l,int r,int rt,int L,int R,int v) {
 59     if (L <= l && r <= R) {
 60         mx[rt] += v; tag[rt] += v;
 61         return ;
 62     }
 63     pushdown(rt);
 64     int mid = (l + r) >> 1;
 65     if (L <= mid) update(lson, L, R, v);
 66     if (R > mid) update(rson, L, R, v);
 67     pushup(rt);
 68 }
 69 int query(int l,int r,int rt,int L,int R) {
 70     if (L <= l && r <= R) {
 71         return mx[rt];
 72     }
 73     pushdown(rt);
 74     int mid = (l + r) >> 1, res = 0;
 75     if (L <= mid) res = query(lson, L, R);
 76     if (R > mid) res = max(res, query(rson, L, R));
 77     return res;
 78 }
 79 
 80 void solve() {
 81     int n = read(), m = read();
 82     LL sum = 0;
 83     int Q = 0;
 84     for (int i=1; i<=n; ++i) {
 85         int l = read() + 1, r = read() + 1, v = read();
 86         q[++Q] = Que(l, r, v);
 87         if (l > r) q[Q].r += m;
 88         else q[++Q] = Que(l + m, r + m, v);
 89         sum += q[Q].v;        
 90     }
 91     if (sum > m) {
 92         puts("No"); return ;
 93     }
 94     
 95     int cnt = 0;
 96     for (int i=1; i<=Q; ++i) Num[++cnt] = q[i].l, Num[++cnt] = q[i].r;
 97     sort(Num + 1, Num + cnt + 1);
 98     int lim = cnt; cnt = 1;
 99     for (int i=2; i<=lim; ++i) if (Num[cnt] != Num[i]) Num[++cnt] = Num[i];
100     for (int i=1; i<=Q; ++i) {
101         q[i].l = lower_bound(Num + 1, Num + cnt + 1, q[i].l) - Num;
102         q[i].r = lower_bound(Num + 1, Num + cnt + 1, q[i].r) - Num;
103     }
104     
105     n = cnt;
106     sort(q + 1, q + Q + 1);
107     build(Root);
108     for (int i=1; i<=Q; ++i) {
109         update(Root, 1, q[i].l, q[i].v);
110         if (query(Root, 1, q[i].l) > Num[q[i].r]) {
111             puts("No"); return; 
112         }
113     }
114     puts("Yes");
115 }
116 int main() {
117     int T = read();
118     while (T--) solve();
119     return 0;
120 }

猜你喜欢

转载自www.cnblogs.com/mjtcn/p/9648260.html