11.12 代码源 2024 NOIP 模拟赛 Day 7
挂大疯()
T1
开始想的是先三进制分解再二进制分解,然后发现第一个样例过不去
然后考虑每次除 \(2\) 再找一下最大的 \(3\) 的整次幂,然后第一个样例过不去
改成 while
然后过掉第一个大样例,打表发现每次除的是 \(lowbit\)
然后改改交了
赛后发现当这个数自身合法时我的会 WA
加个特判 \(0 \rightarrow 70\)
正解是 Python 高精()
Python 3
def solve(x):
if x==0:
return []
y=x&-x
if y==x:
return [x]
x//=y
nw=1
while nw*3<=x:
nw*=3
res=solve(x-nw)
res.append(nw)
return [c*y for c in res]
ans=solve(int(input()))
print(len(ans),"\n"+" ".join(map(str,ans)))
T2
开始码的暴力,然后发现修改的是类似往返,碰到第一个不同的改方向
然后迅速码了个 \(O(nq)\) 的
然后发现可以线段树搞,然鹅没码完就结束了
赛后调线段树调洪文力(喜提次劣解)
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a);i<=(b);i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define db(x) cout<<"DEBUG "<<#x<<" = "<<x<<endl;
#define endl '\n'
using namespace std;
//#define SIZE (1<<20)
//char In[SIZE],Out[SIZE],*p1=In,*p2=In,*p3=Out;
//#define getchar() (p1==p2&&(p2=(p1=In)+fread(In,1,SIZE,stdin),p1==p2)?EOF:*p1++)
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}
return x*f;
}
const int N=5e5+509,M=1e6+509,mod=998244353;
int n,q,a[N];
char s[N];
//类似于往返
//碰到第一个不同的改方向
struct stt
{
int l,r,sum0,sum1,sum,f;
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define l(p) t[p].l
#define r(p) t[p].r
#define len(p) (t[p].r-t[p].l+1)
#define sum0(p) t[p].sum0
#define sum1(p) t[p].sum1
#define sum(p) t[p].sum
#define f(p) t[p].f
}t[N<<1];
inline void pushup(int p)
{
sum0(p)=sum0(ls(p))+sum0(rs(p));
sum1(p)=sum1(ls(p))+sum1(rs(p));
sum(p)=sum(ls(p))+sum(rs(p));
}
inline void pushdown(int p)
{
if(!f(p)) return;
f(ls(p))^=1,f(rs(p))^=1;
swap(sum0(ls(p)),sum1(ls(p)));
sum(ls(p))=len(ls(p))-sum(ls(p));
swap(sum0(rs(p)),sum1(rs(p)));
sum(rs(p))=len(rs(p))-sum(rs(p));
f(p)=0;
}
void build(int p,int l,int r)
{
l(p)=l,r(p)=r;
if(l==r)
{
sum0(p)=(a[l]==0)?l:0;
sum1(p)=(a[l]==1)?l:0;
sum(p)=(a[l]==1);
return;
}
int mid=r+l>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
pushup(p);
}
void change(int p,int l,int r)
{
if(r<l(p)||l>r(p)) return;
if(l<=l(p)&&r(p)<=r)
{
swap(sum0(p),sum1(p));
sum(p)=len(p)-sum(p);
f(p)^=1;return;
}
pushdown(p);
int mid=l(p)+r(p)>>1;
if(mid>=l) change(ls(p),l,r);
if(mid<r) change(rs(p),l,r);
pushup(p);
}
int ask0(int p,int l,int r)
{
if(r<l(p)||l>r(p)) return 0;
if(l<=l(p)&&r(p)<=r) return sum0(p);
pushdown(p);
int mid=l(p)+r(p)>>1,res=0;
if(mid>=l) res+=ask0(ls(p),l,r);
if(mid<r) res+=ask0(rs(p),l,r);
pushup(p);
return res;
}
int ask1(int p,int l,int r)
{
if(r<l(p)||l>r(p)) return 0;
if(l<=l(p)&&r(p)<=r) return sum1(p);
pushdown(p);
int mid=l(p)+r(p)>>1,res=0;
if(mid>=l) res+=ask1(ls(p),l,r);
if(mid<r) res+=ask1(rs(p),l,r);
pushup(p);
return res;
}
int ask(int p,int l,int r)
{
if(r<l(p)||l>r(p)) return 0;
if(l<=l(p)&&r(p)<=r) return sum(p);
pushdown(p);
int mid=l(p)+r(p)>>1,res=0;
if(mid>=l) res+=ask(ls(p),l,r);
if(mid<r) res+=ask(rs(p),l,r);
pushup(p);
return res;
}
int SubI()
{
int cnt=0;
fd(i,1,n) cnt+=a[i];
int res=cnt;
fd(i,cnt+1,n) if(a[i]) res+=(i-cnt)*2;
fd(i,1,cnt-1) if(!a[i]) res+=(cnt-i)*2;
return res;
}
int SubII()
{
int cnt=ask(1,1,n);
int res=cnt;
// fd(i,cnt+1,n) if(a[i]) res+=(i-cnt)*2;
res+=(ask1(1,cnt+1,n)-ask(1,cnt+1,n)*cnt)*2;
// fd(i,1,cnt-1) if(!a[i]) res+=(cnt-i)*2;
res+=(-ask0(1,1,cnt-1)+(cnt-1-ask(1,1,cnt-1))*cnt)*2;
return res%mod;
}
signed main()
{
// #define FJ
#ifdef FJ
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#else
// freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.12/2024.11/ex_flip3.in","r",stdin);
// freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.12/2024.11/flip.out","w",stdout);
#endif
//#define io
#ifdef io
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
#endif
n=read(),q=read();
scanf("%s",s+1);
fd(i,1,n) a[i]=s[i]-'0';
build(1,1,n);
while(q--)
{
int l=read(),r=read();
change(1,l,r);
printf("%lld\n",SubII());
}
return 0;
}
T3
码的暴力还 T 了
想的贪心还假了
汤完了
T4
好逆天……
总结
- T1 挂 \(70\) 分,练!
- T2 没码完,练!
- T3 暴力写挂,练!
- T4 没码暴力,练!
本文来自博客园,作者:whrwlx,转载请注明原文链接:https://www.cnblogs.com/whrwlx/p/18542578