Codeforces Round #705 (Div. 2) 部分题解
D. GCD of an Array
单点乘并查询序列\(gcd\),\(n,x<=200000\)
对差不多约\(20000\)个素数每个建棵线段树。动态开点即可。
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
template <class I>
inline void read(I &z)
{
z=0;
char c=getchar();int base=1;
while (!isdigit(c) && c!='-') c=getchar();
if (c=='-') c=getchar(),base=-1;
while (isdigit(c)) z=z*10+c-'0',c=getchar();
z*=base;
}
const int N=200010,M=7.5e6,p=1e9+7;
int check[N];
void Euler()
{
for (int i=2;i<=200000;++i)
{
if (check[i]) continue;
check[i]=i;
if (i>=1000) continue;
for (int j=i*i;j<=200000;j+=i) if (!check[j]) check[j]=i;
}
}
struct Segment_Tree
{
struct node { int lc,rc,w; };
int point,root[N];
Segment_Tree(LL _point=1):point(_point) {};
node a[M];
int newnode() { return ++point; }
void pushup(int cur) { a[cur].w=min(a[a[cur].lc].w,a[a[cur].rc].w); }
void update(int cur,int l,int r,int pos,int x)
{
if (l==r) return (void)(a[cur].w+=x);
int mid=l+r>>1;
if (pos<=mid)
{
if (!a[cur].lc) a[cur].lc=newnode();
update(a[cur].lc,l,mid,pos,x);
}
if (pos>mid)
{
if (!a[cur].rc) a[cur].rc=newnode();
update(a[cur].rc,mid+1,r,pos,x);
}
pushup(cur);
}
int inquire(int cur) { return a[cur].w; }
};
Segment_Tree T;
LL ans=1,n,q,x,y;
void add(int cur,int x)
{
while (x!=1)
{
int k=check[x],c=0;
while (check[x]==k) ++c,x/=k;
int last=T.inquire(T.root[k]);
if (!T.root[k]) T.root[k]=T.newnode();
T.update(T.root[k],1,n,cur,c);
int now=T.inquire(T.root[k]);
for (int i=last+1;i<=now;++i) ans=ans*k%p;
}
}
int main(int argc, char const *argv[])
{
read(n),read(q);
Euler();
for (int i=1;i<=n;++i)
{
read(x);
add(i,x);
}
for (int i=1;i<=q;++i)
{
read(x),read(y);
add(x,y);
printf("%lld\n",ans);
}
return 0;
}
E. Enormous XOR
给两个等长的\(0/1\)串\(l和r\)(\(1e6\))(保证\(r\)没有前导零),问从\(l\)到\(r\)的最大子段异或和。
注意到若\(l_1=0\)且\(r_1=1\)则取\(011...1\)和\(100...0\)可得\(111...1\),之后分奇偶讨论\(r\)。若\(r\)为奇数,则\(r\) \(xor\) \((r-1)=1\),\(r\)为偶数类似。
#include<cstdio>
#include<cctype>
#include<cstring>
#define LL long long
using namespace std;
template <class I>
inline void read(I &z)
{
z=0;
char c=getchar();int base=1;
while (!isdigit(c) && c!='-') c=getchar();
if (c=='-') c=getchar(),base=-1;
while (isdigit(c)) z=z*10+c-'0',c=getchar();
z*=base;
}
const int N=1000010;
char l[N],r[N];
int n,fir=1;
int check()
{
for (int i=n;i;--i) if (l[i]!=r[i]) return 0;
return 1;
}
int main(int argc, char const *argv[])
{
read(n);
scanf("%s",l+1),scanf("%s",r+1);
if (l[1]=='0' && r[1]=='1')
{
for (int i=1;i<=n;++i) putchar('1');
return 0;
}
if (r[n]=='1') return printf("%s",r+1),0;
if (check()) return printf("%s",r+1),0;
for (int i=n;i;--i) if (l[i]=='1') l[i]='0'; else { l[i]='1'; break; }
if (check()) printf("%s",r+1);
else r[n]='1',printf("%s",r+1);
return 0;
}

浙公网安备 33010602011771号