考试整理

题解(自己悟吧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
");
            return ;
        }
        else if(flag==0) continue;
        else if(flag1==0&&flag0==0&&flag==1) ans*=2;
    }
    printf("%lld
",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('
');
}
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 == '
' || ch == '
' || ch == '	' || ch == '');
            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 == '
' || ch == '
' || ch == '	' || ch == '');
                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
", 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 = &ll; _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
", 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