【树状数组】2018 ICPC Asia Jakarta Regional Contest H. Lexical Sign Sequence
2021-08-25 21:36:00
# ACM
题链
题目解析
贪心,先将所有的 $0$ 位置都填上 $-1$,对于每一个约束区间 $[L,R]$ 来说,最好先更改靠近 $R$ 的位置,将 $-1$ 变为 $1$ 知道满足约束条件即可;
所以可以先对所有约束条件按照 $R$ 从小到大以及 $L$ 从小到大排序,通过树状数组维护区间和解决;
代码实现
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
| #include <bits/stdc++.h> using namespace std; #define LL long long #define Pair pair<LL ,LL > #define ls rt<<1 #define rs rt<<1|1 #define PI acos(-1.0) #define eps 1e-13 #define mod 1000000009 #define MAXN 50001 #define MS 100005
int n,m; int p[MS]; int v[MS]; int tr[MS]; struct node{ int l,r,c; }a[MS];
bool cmp(node t1,node t2){ if(t1.r == t2.r) return t1.l < t2.l; return t1.r < t2.r; }
int lowbit(int x){ return x&(-x); }
void add(int pos,int val){ for(;pos<=n;pos+=lowbit(pos)) tr[pos] += val; }
int query(int pos){ int ans = 0; for(;pos;pos-=lowbit(pos)) ans += tr[pos]; return ans; }
void solve(){ cin >> n >> m; for(int i=1;i<=n;i++){ cin >> p[i]; if(!p[i]){ p[i] = -1; v[i] = 1; } add(i,p[i]); } for(int i=1;i<=m;i++){ int l,r,c; cin >> l >> r >> c; a[i] = {l,r,c}; } sort(a+1,a+m+1,cmp); int flag = 1; for(int i=1;i<=m;i++){ node t = a[i]; int sum = query(t.r) - query(t.l-1); if(sum >= t.c) continue; int cha = t.c - sum; while(t.r >= t.l && cha > 0){ if(v[t.r]){ v[t.r] = 0; p[t.r] = 1; add(t.r,2); cha -= 2; } t.r--; } if(cha > 0){ flag = 0; break; } } if(flag){ for(int i=1;i<=n;i++){ cout << p[i] << " "; } cout << "\n"; } else cout << "Impossible\n"; }
int main() { ios::sync_with_stdio(false);
int ce = 1;
while(ce--) solve(); return 0; }
|
2021-08-25 21:36:00
# ACM