Codeforces E. Interesting Array (segment tree)

Subject description:

D. Interesting Array
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

We'll call an array of n non-negative integers a[1], a[2], ..., a[n] interesting, if it meets m constraints. The i-th of them constraints consists of three integers li, ri, qi (1 ≤ li ≤ ri ≤ n) meaning that value  should be equal to qi.

Your task is to find any interesting array of n elements or state that such array doesn't exist.

Expression x&y means the bitwise AND of numbers x and y. In programming languages C++, Java and Python this operation is represented as "&", in Pascal — as "and".
Input

The first line contains two integers n, m (1 ≤ n ≤ 105, 1 ≤ m ≤ 105) — the number of elements in the array and the number of limits.

Each of the next m lines contains three integers li, ri, qi (1 ≤ li ≤ ri ≤ n, 0 ≤ qi < 230) describing the i-th limit.
Output

If the interesting array exists, in the first line print "YES" (without the quotes) and in the second line print n integersa[1], a[2], ..., a[n] (0 ≤ a[i] < 230) decribing the interesting array. If there are multiple answers, print any of them.

If the interesting array doesn't exist, print "NO" (without the quotes) in the single line.
Examples
input

3 1
1 3 3

output

YES
3 3 3

input

3 2
1 3 3
1 3 2

output

NO

Ideas:

With sections related issues can be considered a segment tree. This question is to limit time and time again by, the number of constructed array. For example the l th to the number of results r & q, i.e. in the binary representation, and if a result of a one, then the number of all the bits are all of a section, if a result is a zero, then at least a number of the bit to 0 on this interval.

Beginning: all for the moment to know all the numbers on the interval on this one for one, do not know which one of a number that the range is zero and zero. Would like to construct a two-dimensional vector, the number of the array represents a binary violence solve possible outcomes. But it seems the operation is quite complex (programming a little difficult for me this is konjac), also may time out.

Finally: Consider the tree line, take a look at the problem to combine. In the interval [l, r], the assumption and the result of 3 (sample 1), then each number on the interval (sum arrays to implement a segment tree) is a leaf node of the tree line, beginning sum [I] = 0, at a time of restriction, with the sum [k] | = q [i], (q [i] shown and results), i.e., use or operation, we can construct the sum [k] to satisfy an article restrictions, when all restrictions had finished, on to query one upper limit condition given interval and if still equal to q [i], because the conditions just configuration during earlier satisfied are likely to be later the restrictions vary, it indicates that a change in limits of two contradictory, because it is not contradictory constraints, their number should be constructed either equal or structure number one is not the same.

On the demand interval and the segment tree template minor changes. Specifically, the

pushup (k) {sum [k ] = sum [k << 1] + sum [k << 1 | 1] plus change and, in the interrogation operation returns the result of thinking a little bit longer, it seems, and not with too, as noted in the title of the data range (less than 2 ^ 30), on the use of I = 2 ^ 30-1, to place ans + = ··· I & = ··· to return the results.

Caution is time pushdown, and how to return results to return, one more thing: do you think is 30-1 2 << 2 ^ 30-1? wrong! Note that the operator precedence, write (2 << 30) -1

Knowledge Point: segment tree

Code:

 1 #include <iostream>
 2 #define max_n 100005
 3 using namespace std;
 4 int sum[max_n<<2];
 5 int lz[max_n<<2];
 6 int l[max_n];
 7 int r[max_n];
 8 int q[max_n];
 9 int n;
10 int m;
11 int I;
12 void pushup(int k)
13 {
14     sum[k] = sum[k<<1]&sum[k<<1|1];
15 }
16 void pushdown(int k,int ln,int rn)
17 {
18     if(lz[k])
19     {
20         sum[k<<1] |= lz[k];
21         sum[k<<1|1] |= lz[k];
22         lz[k<<1] |= lz[k];
23         lz[k<<1|1] |= lz[k];
24         lz[k] = 0;
25     }
26 }
27 void build(int k,int l,int r)
28 {
29     lz[k] = 0;
30     if(l==r)
31     {
32         sum[k]=0;
33         return;
34     }
35     int mid = (l+r)>>1;
36     build(k<<1,l,mid);
37     build(k<<1|1,mid+1,r);
38     pushup(k);
39 }
40 void update(int k,int L,int R,int l,int r,int val)
41 {
42     if(L<=l&&r<=R)
43     {
44         sum[k] |= val;
45         lz[k] |= val;
46         return;
47     }
48     int mid = (l+r)/2;
49     int ln = mid-l+1;
50     int rn = r-mid;
51     pushdown(k,ln,rn);
52     if(L<=mid) update(k<<1,L,R,l,mid,val);
53     if(mid<R) update(k<<1|1,L,R,mid+1,r,val);
54     pushup(k);
55 }
56 int query(int k,int L,int R,int l,int r)
57 {
58     if(L<=l&&r<=R)
59     {
60         //cout << "k " << k << " " << sum[k] << endl;
61         return sum[k];
62     }
63     int mid = (l+r)>>1;
64     int ln = mid-l+1;
65     int rn = r-mid;
66     pushdown(k,ln,rn);
67     long long I = (long long)(2<<30) - 1;
68     if(L<=mid) I = I&query(k<<1,L,R,l,mid);
69     //cout << "qian " << I << endl;
70     if(mid<R) I = I&query(k<<1|1,L,R,mid+1,r);
71     pushup(k);
72     //cout << "hou " << I << endl;
73     return I;
74 }
75 int main()
76 {
77     cin >> n >> m;
78     build(1,1,n);
79     for(int i = 0;i<m;i++)
80     {
81         cin >> l[i] >> r[i] >> q[i];
82         update(1,l[i],r[i],1,n,q[i]);
83     }
84     for(int i = 0;i<m;i++)
85     {
86         int ans = query(1,l[i],r[i],1,n);
87         if(ans!=q[i])
88         {
89             cout << "NO" << endl;
90             return 0;
91         }
92     }
93     cout << "YES" << endl;
94     for(int i = 1;i<=n;i++)
95     {
96         cout << query(1,i,i,1,n) << " ";
97     }
98     return 0;
99 }

 

Guess you like

Origin www.cnblogs.com/zhanhonhao/p/11221221.html