mzf的考验

题解:

比较水吧

显然是平衡树的操作

然后就是写写写

用对拍来查错相比之下直接样例查还是比较容易的

刚开始没有优化常数没开O2就变成暴力分了smg 开了O2就a了

代码:

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define ll long long
const int N=3e5;
int a[N],rt,x1,x2;
char ss[1<<24],*A=ss,*B=ss;
IL char gc()
{
  return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
}
template<class T>void read(T &x)
{
  rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
  while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
}
struct sgt{
  int v[N][21],data[N],lazy[N],ls[N],rs[N],count2[N],fa[N];
  bool rev[N];
  IL void updata(rint x)
  { 
    count2[x]=count2[ls[x]]+count2[rs[x]]+1;
    rint *a=v[x],*b=v[ls[x]],*c=v[rs[x]],d=data[x];
    rep(i,0,20) a[i]=((d>>i)&1)+b[i]+c[i]; 
 //   rep(i,0,20) v[x][i]=((data[x]>>i)&1)+v[ls[x]][i]+v[rs[x]][i];
  }
  IL void down(rint x)
  {
    if (rev[x])
    {
      rev[ls[x]]^=1; rev[rs[x]]^=1;
      swap(ls[x],rs[x]);
      rev[x]=0;
    }
    if (lazy[x])
    {
      if (ls[x])
      {
        lazy[ls[x]]^=lazy[x]; data[ls[x]]^=lazy[x];
        dep(i,20,0)
          if ((lazy[x]>>i)&1) v[ls[x]][i]=count2[ls[x]]-v[ls[x]][i];
      }
      if (rs[x])
      {
        lazy[rs[x]]^=lazy[x]; data[rs[x]]^=lazy[x];
        dep(i,20,0)
          if ((lazy[x]>>i)&1) v[rs[x]][i]=count2[rs[x]]-v[rs[x]][i];
      }
      lazy[x]=0;
    }
  }
  void rotate(rint x,rint y)
  {
    rint f1=fa[x];
    if (y==1)
    {
      rs[f1]=ls[x];
      if (ls[x]) fa[ls[x]]=f1;
    } else
    {
      ls[f1]=rs[x];
      if (rs[x]) fa[rs[x]]=f1;
    }
    fa[x]=fa[f1];
    if (fa[f1])
      if (ls[fa[f1]]==f1) ls[fa[f1]]=x;
      else rs[fa[f1]]=x;
    fa[f1]=x;
    if (y==1) ls[x]=f1; else rs[x]=f1;
    updata(f1); updata(x);
  }
  void dfs(int x)
  {
    if (fa[x]) dfs(fa[x]);
    down(x);
  }
  void splay(rint x,rint y)
  {
    dfs(x);
    rint f1=fa[x];
    while (f1!=y)
    {
      if (fa[f1]==y)
        if (ls[f1]==x) rotate(x,2); else rotate(x,1);
      else 
      if (ls[fa[f1]]==f1)
         if (ls[f1]==x) rotate(f1,2),rotate(x,2);
            else rotate(x,1),rotate(x,2);
      else if (rs[f1]==x) rotate(f1,1),rotate(x,1);
        else rotate(x,2),rotate(x,1);
      f1=fa[x];
    }
    if (!y) rt=x;
  }
  IL int search(rint x)
  {
    rint y=rt;
    while (y)
    {
      down(y);
      if (count2[ls[y]]+1==x) return(y);
      if (count2[ls[y]]>=x) y=ls[y];
      else x-=count2[ls[y]]+1,y=rs[y];
    }
  }
  IL void split(rint x,rint y)
  {
    x1=search(x);
    x2=search(y);
    splay(x2,0);
    splay(x1,x2);
    down(x2); down(x1); x1=rs[x1];
  }
}S;
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  int n,m;
  read(n); read(m);
  rep(i,1,n) read(a[i]);
  rep(i,1,n+1)
  { 
    S.rs[i]=i+1,S.count2[i]=1,S.fa[i+1]=i,S.data[i]=a[i-1];
  }
  S.splay(n+2,0);
  rep(i,1,m)
  {
    int kk,x,y,z;
    read(kk); read(x); read(y);
    if (kk==1)
    {
      S.split(x,y+2);
      S.rev[x1]^=1;
      S.splay(x1,0);
    }
    if (kk==2)
    {
      read(z);
      S.split(x,y+2);
      S.lazy[x1]^=z;
      S.data[x1]^=z;
      rep(i,0,20) if ((z>>i)&1) S.v[x1][i]=S.count2[x1]-S.v[x1][i];
      S.splay(x1,0);
    }
    if (kk==3)
    {
      S.split(x,y+2);
      ll ans=0;
      dep(i,20,0) ans+=1ll*(1<<i)*S.v[x1][i];
      cout<<ans<<endl; 
    }
  }
  return 0;
}

 

转载于:https://www.cnblogs.com/yinwuxiao/p/9623821.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我无法直接解码 Base64 编码的字符串,因为我无法处理二进制数据。然而,如果您使用标准的 C 语言库,您可以使用 `<stdlib.h>` 和 `<stdio.h>` 头文件中的函数来解码 Base64 字符串。 以下是一个简单的示例代码,使用 C 标准库函数来解码 Base64 编码的字符串: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int base64_decode(const char *encoded_data, size_t encoded_length, unsigned char *decoded_data, size_t *decoded_length) { int i, j; unsigned char a, b, c, d; if (encoded_length % 4 != 0) { return -1; // Invalid Base64 string } *decoded_length = (encoded_length / 4) * 3; for (i = 0, j = 0; i < encoded_length; i += 4, j += 3) { a = strchr(base64_chars, encoded_data[i]) - base64_chars; b = strchr(base64_chars, encoded_data[i+1]) - base64_chars; c = strchr(base64_chars, encoded_data[i+2]) - base64_chars; d = strchr(base64_chars, encoded_data[i+3]) - base64_chars; decoded_data[j] = (a << 2) | (b >> 4); decoded_data[j+1] = (b << 4) | (c >> 2); decoded_data[j+2] = (c << 6) | d; } return 0; } int main() { const char *encoded_data = "bXNjaAF4nFVS3U/TUBQ/Xbu2ax08+Cfw3MgSCPGRGPZPLDwU2mDN1s52hfhs/HhBEiMmk4iiA2aMfGTTTWbg3T9Dd9sRTXg3YD3nVti4ye2953c+fuf0/mAcciJIrlmxQS9MssZu/KbF3jVBt+xg0XeqNcdzAUAumwt2OYBs6ezt53kNxhZ8x1qyjUXPtUKnBnolLNcco+rbQQA3q2UzqJmuE1YoYNl+4PmgVb0V2zdcz7IhX3buh45l+F5Ys30YHxZLY8f/+++F7iJvQA3dsmdaGKtXzCAwLN9ZRkOpIJ25ZGODt4CWglukiyiAAJn0LhEKSZKcc1ROUXWIZhDFFBEPSZW4W0ougG4y4hLiKohZrAdKkvz9jXubmyOVZTRVShXTLmhlRAVNIQuQ5Y4MZf/C/R4bkag++eUrv0KJEm+fuFWaIovk/MBQFT8S1Yhxb2HbfFw6BGpPSQliTkCmPGyPmlIuvZvcVIdsAuRSmhzRCKDx2UG/Pop+NYqeMv3kTORIZ8jhTZEE+D4iJG3Qbp5+OIx6W9H608HJRvSyzlZbbG1f6/eesc5O/3h30NmPXxyyepPcB22N9Y4Ge3v9biPunbDuDntyNGjvaoZRmpicnJsu4pqPNtdZoz3Yb7Ptr/3uavSwdfr4uVZauevU7PmF+GOdPWpFrebZt1elieLs7GxxCpPiT4enG81+9ws7WIvq7cvw+LjB1jo89M5cEaMxdGZmunB7eqYwBTSsejnsa/ytN1IR/OAiECBPKiP0msrypDIJUZXeJ5+qK0/qQl1Bcp5cJOcgJn8QlxHnwhnjhckPqSmNPt/YqGD/ATJ9J5E="; size_t encoded_length = strlen(encoded_data); size_t decoded_length = 0; // 计算解码后的数据长度 base64_decode(encoded_data, encoded_length, NULL, &decoded_length); // 分配内存 unsigned char *decoded_data = malloc(decoded_length + 1); if (decoded_data == NULL) { printf("内存分配失败\n"); return 1; } // 进行解码 if (base64_decode(encoded_data, encoded_length, decoded_data, &decoded_length) != 0) { printf("解码失败\n"); free(decoded_data); return 1; } // 打印解码后的数据 printf("解码后的数据: %s\n", decoded_data); // 释放内存 free(decoded_data); return 0; } ``` 请注意,这只是一个简单的示例代码,可能无法处理所有情况。如果您需要更复杂的 Base64 解码功能,建议使用第三方库或更完善的解码实现。希望这可以帮助到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值