题解(自己悟吧qwq):
首先,看到这个题,我们显然会打一个暴力,然后比较大佬的人就会这样打(45分):
#include<bits/stdc++.h> using namespace std; inline int read() { int ans=0; char last=‘ ‘,ch=getchar(); while(ch<‘0‘||ch>‘9‘) last=ch,ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) ans=ans*10+ch-‘0‘,ch=getchar(); if(last==‘-‘) ans=-ans; return ans; } int n,m,q; char s[100010][31]; long long ans; inline void work(int l,int r) { ans=1; for(int t=1;t<=n;t++) { int flag1=0; int flag0=0; int flag=0; for(int j=l;j<=r;j++) { if(s[j][t]==‘1‘) flag1=1; if(s[j][t]==‘0‘) flag0=1; if(s[j][t]==‘?‘) flag=1; } if(flag1==1&&flag0==1) { printf("0\n"); return ; } else if(flag==0) continue; else if(flag1==0&&flag0==0&&flag==1) ans*=2; } printf("%lld\n",ans); } int main() { freopen("lin.in","r",stdin); freopen("lin.out","w",stdout); n=read(),m=read(),q=read(); for(int i=1;i<=m;i++) { scanf("%s",s[i]+1); } int k,l,r; for(int i=1;i<=q;i++) { k=read(); if(k==1) { int t=read(); scanf("%s",s[t]+1); } if(k==0) { l=read(),r=read(); work(l,r); } } return 0; }
更大佬的人便会这样打(70分):
#include <bits/stdc++.h> using namespace std; template <class T> inline void read(T &num) { bool flag = 0; num = 0; char c = getchar(); while ((c < ‘0‘ || c > ‘9‘) && c != ‘-‘) c = getchar(); if (c == ‘-‘) { flag = 1; c = getchar(); } num = c - ‘0‘; c = getchar(); while (c >= ‘0‘ && c <= ‘9‘) num = (num << 3) + (num << 1) + c - ‘0‘, c = getchar(); if (flag) num *= -1; } template <class T> inline void output(T num) { if (num < 0) { putchar(‘-‘); num = -num; } if (num >= 10) output(num / 10); putchar(num % 10 + ‘0‘); } template <class T> inline void outln(T num) { output(num); putchar(‘\n‘); } template <class T> inline void outps(T num) { output(num); putchar(‘ ‘); } const int N = 31, M = 100010; int n, m, q; struct segment { char val[M]; bool all1[M * 4]; bool all0[M * 4]; void init(int node, int nl, int nr) { if (nl < nr) { int mid = (nl + nr) >> 1; init(node * 2, nl, mid); init(node * 2 + 1, mid + 1, nr); all1[node] = all1[node * 2] & all1[node * 2 + 1]; all0[node] = all0[node * 2] & all0[node * 2 + 1]; } else { if (val[nl] == ‘?‘) all1[node] = all0[node] = 1; else { all1[node] = val[nl] == ‘1‘; all0[node] = val[nl] == ‘0‘; } } } void modify(int node, int nl, int nr, int x, char va) { if (val[x] == va) return; if (nl < nr) { int mid = (nl + nr) >> 1; if (x <= mid) { modify(node * 2, nl, mid, x, va); } else { modify(node * 2 + 1, mid + 1, nr, x, va); } all1[node] = all1[node * 2] & all1[node * 2 + 1]; all0[node] = all0[node * 2] & all0[node * 2 + 1]; } else { if (va == ‘?‘) all1[node] = all0[node] = 1; else { all1[node] = va == ‘1‘; all0[node] = va == ‘0‘; } val[x] = va; } } pair<bool, bool> query(int node, int nl, int nr, int l, int r) { if (l <= nl && r >= nr) { return make_pair(all1[node], all0[node]); } int mid = (nl + nr) >> 1; bool a1 = true, a0 = true; if (l <= mid) { auto lo = query(node * 2, nl, mid, l, r); a1 &= lo.first; a0 &= lo.second; } if (r >= mid + 1) { auto lo = query(node * 2 + 1, mid + 1, nr, l, r); a1 &= lo.first; a0 &= lo.second; } return make_pair(a1, a0); } void dfs(int node, int nl, int nr) { if (nl < nr) { int mid = (nl + nr) >> 1; dfs(node * 2, nl, mid); dfs(node * 2 + 1, mid + 1, nr); } outps(nl); outps(nr); outps(all1[node]); outln(all0[node]); } } segs[N]; int main() { freopen("lin.in", "r", stdin); freopen("lin.out", "w", stdout); read(n); read(m); read(q); char ch; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { do { ch = getchar(); } while (ch == ‘ ‘ || ch == ‘\n‘ || ch == ‘\r‘ || ch == ‘\t‘ || ch == ‘\0‘); segs[j].val[i] = ch; } } for (int i = 1; i <= n; i++) { segs[i].init(1, 1, m); } while (q--) { bool opt; read(opt); if (opt == 0) { int l, r; read(l); read(r); int ans = 1; for (int i = 1; i <= n; i++) { auto lo = segs[i].query(1, 1, m, l, r); ans *= (lo.first + lo.second); } outln(ans); } else { int pos; read(pos); for (int i = 1; i <= n; i++) { do { ch = getchar(); } while (ch == ‘ ‘ || ch == ‘\n‘ || ch == ‘\r‘ || ch == ‘\t‘ || ch == ‘\0‘); segs[i].modify(1, 1, m, pos, ch); } } } }
正解就比较有趣了:
#include <cstdio> template <typename T> inline void qr(T &x) { char ch = getchar(), lst = ‘ ‘; while ((ch > ‘9‘) || (ch < ‘0‘)) lst = ch, ch=getchar(); while ((ch >= ‘0‘) && (ch <= ‘9‘)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar(); if (lst == ‘-‘) x = -x; } const int maxn = 100010; int n, m, q; char s[maxn][35]; #ifdef ONLINE_JUDGE int Ans; #endif struct Tree { Tree *ls, *rs; int l, r, x, y; bool leg; Tree() { ls = rs = NULL; l = r = x = y = 0; leg = true; } void pushup() { if (!(this->ls->leg && this->rs->leg)) { this->leg = false; } else { if ((this->ls->x & this->rs->x) & (this->ls->y ^ this->rs->y)) { this->leg = false; } else { this->leg = true; this->x = this->ls->x | this->rs->x; this->y = this->ls->y | this->rs->y; } } } }; Tree *rot; void ReadStr(char *p); void Update(const int x); void Query(const int l, const int r); void update(Tree *const u, const int p); Tree query(Tree *u, const int l, const int r); void build(Tree *const u, const int l, const int r); int main() { freopen("lin.in", "r", stdin); freopen("lin.out", "w", stdout); qr(n); qr(m); qr(q); for (int i = 1; i <= m; ++i) { ReadStr(s[i] + 1); } build(rot = new Tree, 1, m); int opt, l, r; while (q--) { opt = 0; qr(opt); if (opt == 0) { l = r = 0; qr(l); qr(r); Query(l, r); } else { l = 0; qr(l); ReadStr(s[0] + 1); Update(l); } } #ifdef ONLINE_JUDGE printf("%d\n", Ans); #endif return 0; } void ReadStr(char *p) { do *p = getchar(); while ((*p != ‘0‘) && (*p != ‘1‘) && (*p != ‘?‘)); do *(++p) = getchar(); while ((*p == ‘0‘) || (*p == ‘1‘) || (*p == ‘?‘)); *p = 0; } void build(Tree *const u, const int l, const int r) { if ((u->l = l) == (u->r = r)) { for (int i = 1; i <= n; ++i) { if (s[l][i] != ‘?‘) { u->x |= 1 << i; if (s[l][i] == ‘1‘) { u->y |= 1 << i; } } } } else { int mid = (l + r) >> 1; build(u->ls = new Tree, l, mid); build(u->rs = new Tree, mid + 1, r); u->pushup(); } } Tree query(Tree *u, const int l, const int r) { if ((u->l > r) || (u->r < l)) return Tree(); if ((u->l >= l) && (u->r <= r)) return *u; Tree _ret; auto ll = query(u->ls, l, r), rr = query(u->rs, l, r); _ret.ls = ≪ _ret.rs = &rr; _ret.pushup(); return _ret; } void Query(const int l, const int r) { auto _ret = query(rot, l, r); if (!_ret.leg) { #ifndef ONLINE_JUDGE puts("0"); #endif } else { int ans = 1; for (int i = 1; i <= n; ++i) if (!(_ret.x & (1 << i))) { ans <<= 1; } #ifdef ONLINE_JUDGE Ans ^= ans; #else printf("%d\n", ans); #endif } } void update(Tree *u, const int p) { if (u->ls) { if (u->ls->r >= p) { update(u->ls, p); } else { update(u->rs, p); } u->pushup(); } else { *u = Tree(); u->l = u->r = p; for (int i = 1; i <= n; ++i) { if (s[0][i] != ‘?‘) { u->x |= 1 << i; if (s[0][i] == ‘1‘) { u->y |= 1 << i; } } } } } void Update(const int x) { update(rot, x); }
原文:https://www.cnblogs.com/gongcheng456/p/11093288.html