Created
October 24, 2014 18:50
-
-
Save karupayun/a21a1d78f79afa5fb380 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cstdio> | |
#include <cstdlib> | |
#include <cstring> | |
#include <string> | |
#include <vector> | |
#include <cmath> | |
#include <queue> | |
#include <set> | |
#include <map> | |
using namespace std; | |
#define dprint(v) cout << #v"=" << v << endl | |
#define forr(i, a, b) for(int i=(a); i<(b); i++) | |
#define forn(i, n) forr(i, 0, n) | |
#define dforn(i, n) for(int i=(n)-1; i>=0; i--) | |
#define forall(it,v) for(typeof((v).begin()) it=(v).begin();it!=(v).end();++it) | |
#define sz(c) ((int)c.size()) | |
#define zero(v) memset(v, 0, sizeof(v)) | |
typedef long long ll; | |
#define ii pair<int, int> | |
#define mkp make_pair | |
#define fst first | |
#define snd second | |
#define pb push_back | |
#define tipo int | |
#define INF 1000 | |
//Dado un arreglo y una operacion asociativa con neutro, get(i, j) opera sobre el rango [i, j). | |
typedef int Elem;//Elem de los elementos del arreglo | |
typedef int Alt;//Elem de la alteracion | |
#define operacion(x,y) (x|y) | |
const Elem neutro=0; const Alt neutro2=0; | |
#define MAXN 100010 | |
struct RMQ{ | |
int sz; | |
Elem t[4*MAXN]; | |
Alt dirty[4*MAXN];//las alteraciones pueden ser de distinto Elem | |
Elem &operator[](int p){return t[sz+p];} | |
void init(int n){//O(nlgn) | |
sz = 1 << (32-__builtin_clz(n)); | |
forr(i, sz, 2*sz) t[i]=neutro; | |
forn(i, 2*sz) dirty[i]=neutro2; | |
} | |
void push(int n, int a, int b){//propaga el dirty a sus hijos | |
if(dirty[n]!=0){ | |
t[n]|=dirty[n];//altera el nodo | |
if(n<sz){ | |
dirty[2*n]|=dirty[n]; | |
dirty[2*n+1]|=dirty[n]; | |
} | |
dirty[n]=0; | |
} | |
} | |
Elem get(int i, int j, int n, int a, int b){//O(lgn) | |
if(j<=a || i>=b) return neutro; | |
push(n, a, b);//corrige el valor antes de usarlo | |
if(i<=a && b<=j) return t[n]; | |
int c=(a+b)/2; | |
return operacion(get(i, j, 2*n, a, c), get(i, j, 2*n+1, c, b)); | |
} | |
Elem get(int i, int j){return get(i,j,1,0,sz);} | |
//altera los valores en [i, j) con una alteracion de val | |
void alterar(Alt val, int i, int j, int n, int a, int b){//O(lgn) | |
push(n, a, b); | |
if(j<=a || i>=b) return; | |
if(i<=a && b<=j){ | |
dirty[n] |=val; | |
push(n, a, b); | |
return; | |
} | |
int c=(a+b)/2; | |
alterar(val, i, j, 2*n, a, c), alterar(val, i, j, 2*n+1, c, b); | |
t[n]=operacion(t[2*n], t[2*n+1]);//por esto es el push de arriba | |
} | |
void alterar(Alt val, int i, int j){alterar(val,i,j,1,0,sz);} | |
}rmq; | |
struct RMQ2{ | |
struct nodo{ | |
int k, s; | |
}t[4*MAXN]; | |
int sz; | |
nodo &operator[](int p){return t[sz+p];} | |
void init(int n){//O(nlgn) | |
sz = 1 << (32-__builtin_clz(n)); | |
forn(i, 2*sz) t[i].k=t[i].s=0; | |
} | |
ll get(int K, int n=1){//O(lgn) | |
if(!K) return 0; | |
if(t[n].k<K) return INF; | |
if(n>=sz) return (t[n].s/t[n].k)*K; | |
if(t[2*n].k>=K) return get(K, 2*n); | |
return t[2*n].s+get(K-t[2*n].k, 2*n+1); | |
} | |
void insert(int p, ll val){//O(lgn) | |
for(p+=sz; p>0;){ | |
t[p].s&=val; | |
t[p].k++; | |
p/=2; | |
} | |
} | |
}rmq2; | |
struct RMQ3{ | |
#define LVL 18 | |
tipo vec[LVL][1<<(LVL+1)]; | |
tipo &operator[](int p){return vec[0][p];} | |
tipo get(int i, int j) {//intervalo [i,j) | |
int p = 31-__builtin_clz(j-i); | |
return min(vec[p][i],vec[p][j-(1<<p)]); | |
} | |
void build(int n) {//O(nlogn) | |
int mp = 31-__builtin_clz(n); | |
forn(p, mp) forn(x, n-(1<<p)) | |
vec[p+1][x] = min(vec[p][x], vec[p][x+(1<<p)]); | |
} | |
}; | |
int op[100010][3]; | |
struct RMQ a; | |
struct RMQ3 b; | |
int v [100010]; | |
int m,n; | |
int main() | |
{ | |
#ifndef ONLINE_JUDGE | |
freopen("d.in", "r", stdin); | |
#endif | |
while (cin >> n >> m){ | |
a.init(n); | |
forn (i,m){ | |
cin >> op[i][0] >> op[i][1] >> op[i][2]; | |
a.alterar (op[i][2], op[i][0]-1, op[i][1]); | |
} | |
forn (i,n){ | |
b.vec[i] = (int)a.get (i,i+1); | |
cerr << a.get(i,i+1) << endl; | |
} | |
b.build(n); | |
bool found = true; | |
forn (i,m){ | |
cout << b.get (op[i][0], op[i][1]) << " " << op[i][2] << endl; | |
if (b.get (op[i][0]-1, op[i][1]) != op[i][2]){ | |
found = false; | |
break; | |
} | |
} | |
if (found){ | |
cout << "YES\n"; | |
forn (i, n-1) | |
cout << a.get(i,i+1) << " "; | |
cout << a.get(n-1,n) << endl; | |
} | |
else | |
cout << "NO\n"; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment