UVA 1493 DRAW A MASS

8758 ワード

1つ目は、線分ツリーのバージョンを直接上書きするだけです.
#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cctype>
#include <cmath>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int n,m;
const int N = 211;
const int M = 51111;
int color[N][M<<2];
void build(int l,int r,int rt,int i){
  color[i][rt] = 0;
  if(l==r) return ;
  int m = (l+r)>>1;
  build(lson,i);
  build(rson,i);
}
void push_down(int rt,int i){
  if(color[i][rt]){
    color[i][rt<<1]=color[i][rt<<1|1]=color[i][rt];
    color[i][rt] = 0;
  }
}
void update(int l,int r,int rt,int L,int R,int val,int i){
  if(L<=l&&r<=R){
     color[i][rt] = val;
     return ;
  }
  push_down(rt,i);
  int m = (l+r)>>1;
  if(L<=m) update(lson,L,R,val,i);
  if(R >m) update(rson,L,R,val,i);
}
int query(int l,int r,int rt,int posi,int i){
  if(color[i][rt]||l==r){
     return color[i][rt];
  }
  int m = (l+r)>>1;
  if(posi<=m) return query(lson,posi,i);
  return query(rson,posi,i);
}
int xc, yc, r, c, l , w;
//xc, yc, r, c;
void circle(int i,int& L,int& R){
  int te = r*r - (i-xc)*(i-xc);
  if(te<0||i<xc-r||i>xc+r){
    L = 1; R = 0; return ;
  }
  te = floor(sqrt(te*1.0));
  L = max(yc-te,1);
  R = min(yc+te,m);
 // printf("%d --> %d %d
",i,L,R); } //xc, yc, r, c£» void diamond(int i,int& L,int& R){ int te = r - abs(i-xc); if(te<0){ L = 1; R = 0; return ; } L = max(yc-te,1); R = min(yc+te,m); } //xc, yc, l, w, c, void rectangle(int i,int& L,int& R){ if(i<xc||i>xc+l-1) { L = 1; R = 0; return ; } L = ceil(max(yc*1.0,1.0)); R = floor(min(yc+w-1.0,m*1.0)); } //xc, yc, w, c void triangle(int i,int& L,int& R){ if(i<xc || i >= xc +(w+1)/2){ L= 1; R= 0; return ; } int dis=(w-1)/2-(i-xc); L = max(yc-dis,1); R = min(yc+dis,m); } int main() { int Q; char cmd[100]; while(scanf("%d %d %d",&n,&m,&Q)==3){ for(int i=1;i<=n;i++) build(1,m,1,i); while(Q--){ scanf("%s",cmd); if(cmd[0]=='C'){ scanf("%d %d %d %d",&xc, &yc, &r, &c); xc++; yc++; for(int i=1;i<=n;i++){ int L,R; circle(i,L,R); if(L <= R){ update(1,m,1,L,R,c,i); } } } else if(cmd[0]=='D'){ scanf("%d %d %d %d",&xc, &yc, &r, &c); xc++; yc++; for(int i=1;i<=n;i++){ int L,R; diamond(i,L,R); if(L <= R){ update(1,m,1,L,R,c,i); } } } else if(cmd[0]=='T'){ scanf("%d %d %d %d",&xc, &yc, &w, &c); xc++; yc++; for(int i=1;i<=n;i++){ int L,R; triangle(i,L,R); if(L <= R){ update(1,m,1,L,R,c,i); } } } else { scanf("%d %d %d %d %d",&xc, &yc,&l, &w, &c); xc++; yc++; for(int i=1;i<=n;i++){ int L,R; rectangle(i,L,R); if(L <= R){ update(1,m,1,L,R,c,i); } } } } //void show(); show(); int cnt[10]={0}; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cnt[query(1,m,1,j,i)]++; for(int i=1;i<=9;i++) { if(i>1) printf(" "); printf("%d",cnt[i]); } printf("
"); } return 0; } void show(){ printf("*****************
"); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ printf("%d",query(1,m,1,j,i)); } printf("
"); } }

2つ目は、キャッシュされた後、逆順序で上書きされ、シェーディングされていない点が必要であればシェーディングされ、類似したステータス圧縮関数を使用して、変更された点の次の上書きされていない点を求めます.
次のプログラムの入力は掛けましたが、まだ掛けないで走るのが速くて、何も言いません.
#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cctype>
#include <cmath>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int n,m;
const int N = 211;
const int M = 51111;
int color[N][M],jump[N][M],cnt[10];
int xc, yc, r, c, l , w;
int find(int st,int i){
  if(!color[i][jump[i][st]]) return jump[i][st];
  return jump[i][st] = find(jump[i][st],i);
}
void update(int st,int ed,int i){
  for(int j=st;j<=ed;){
     if(!color[i][j]) {
        color[i][j] = 1;
        cnt[c]++;
     }
     j=find(j,i);
  }
}
template <class T>
inline bool scan_d(T &ret) {
    char c; int sgn;
    if(c=getchar(),c==EOF) return 0; //EOF
    while(c!='-'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    ret*=sgn;
    return 1;
}
struct node{
  char cmd;
  int data[10];
}cun[M];
void read_input(int i){
  char str[100];
  scanf("%s",str);
  cun[i].cmd=str[0];
  scan_d(cun[i].data[0]);
  scan_d(cun[i].data[1]);
  scan_d(cun[i].data[2]);
  scan_d(cun[i].data[3]);
  if(str[0]=='R')
    scan_d(cun[i].data[4]);
}
//xc, yc, r, c;
void circle(int i,int& L,int& R){
  int te = r*r - (i-xc)*(i-xc);
  if(te<0||i<xc-r||i>xc+r){
    L = 1; R = 0; return ;
  }
  te = floor(sqrt(te*1.0));
  L = max(yc-te,1);
  R = min(yc+te,m);
 // printf("%d --> %d %d
",i,L,R); } //xc, yc, r, c£» void diamond(int i,int& L,int& R){ int te = r - abs(i-xc); if(te<0){ L = 1; R = 0; return ; } L = max(yc-te,1); R = min(yc+te,m); } //xc, yc, l, w, c, void rectangle(int i,int& L,int& R){ if(i<xc||i>xc+l-1) { L = 1; R = 0; return ; } L = ceil(max(yc*1.0,1.0)); R = floor(min(yc+w-1.0,m*1.0)); } //xc, yc, w, c void triangle(int i,int& L,int& R){ if(i<xc || i >= xc +(w+1)/2){ L= 1; R= 0; return ; } int dis=(w-1)/2-(i-xc); L = max(yc-dis,1); R = min(yc+dis,m); } int main() { int Q; char cmd[100]; while(scanf("%d %d %d",&n,&m,&Q)==3){ for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) color[i][j] = 0; for(int i=1;i<=n;i++){ for(int j=1;j<=m+1;j++) jump[i][j]=j+1; } for(int i=1;i<=9;i++) cnt[i] = 0; for(int i=1;i<=Q;i++) read_input(i); for(int g=Q;g>=1;g--){ if(cun[g].cmd=='C'){ xc = cun[g].data[0]; yc = cun[g].data[1]; r = cun[g].data[2]; c = cun[g].data[3]; xc++; yc++; for(int i=1;i<=n;i++){ int L,R; circle(i,L,R); if(L <= R){ update(L,R,i); } } } else if(cun[g].cmd=='D'){ xc = cun[g].data[0]; yc = cun[g].data[1]; r = cun[g].data[2]; c = cun[g].data[3]; xc++; yc++; for(int i=1;i<=n;i++){ int L,R; diamond(i,L,R); if(L <= R){ // printf("%d %d
",L,R); update(L,R,i); } } } else if(cun[g].cmd=='T'){ xc = cun[g].data[0]; yc = cun[g].data[1]; w = cun[g].data[2]; c = cun[g].data[3]; xc++; yc++; for(int i=1;i<=n;i++){ int L,R; triangle(i,L,R); if(L <= R){ update(L,R,i); } } } else { xc = cun[g].data[0]; yc = cun[g].data[1]; l = cun[g].data[2]; w = cun[g].data[3]; c = cun[g].data[4]; xc++; yc++; for(int i=1;i<=n;i++){ int L,R; rectangle(i,L,R); if(L <= R){ update(L,R,i); } } } } for(int i=1;i<=9;i++) { if(i>1) printf(" "); printf("%d",cnt[i]); } printf("
"); } return 0; }