签到题:
这也算签到题!!!(想了我0.5hour)
找规律,,当值为x时,满足ax=by,a+b=2^(x+1),a,b为奇数,然后乱七八糟化简,分块就好了。。
#include <bits/stdc++.h>
#define ll long long
#define num(x) ((x+1)>>1)
using namespace std;
ll n,ans;
int main()
{
scanf("%lld",&n);
for (ll i=1,j=4;(j>>1)+1<=n;i++,j<<=1)
{
ll from,next;
for (from=(j>>1)+1,next;from<=min(j-1,n);from=next+1)
{
next=min(n/(n/from),j-1);
ans+=(num(next)-num(from-1))*(n/from)*i;
}
}
printf("%lld\n",ans*2);
return 0;
}
总统选举:
考虑当前答案为x,权值为v,每多一个非x数,v--,等于x,v++,v<0时就换一个,如果区间中有答案,这显然是对的,然后就可以线段树节点合并啦。
判断答案是不是对的,就每个权值开一棵splay,判断大小就好了,注意每次维护答案
#include <bits/stdc++.h>
#define gc getchar()
#define N 500002
#define ll long long
#define Root 1,1,n
#define NOW int cur,int l,int r
#define mid (l+r>>1)
#define lc cur<<1
#define rc lc|1
#define lson lc,l,mid
#define rson rc,mid+1,r
using namespace std;
namespace fastIO{
#define BUF_SIZE 100000
#define OUT_SIZE 100000
#define ll long long
//fread->read
bool IOerror=0;
inline char nc(){
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if (p1==pend){
p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
if (pend==p1){IOerror=1;return -1;}
//{printf("IO error!\n");system("pause");for (;;);exit(0);}
}
return *p1++;
}
inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
inline void read(int &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(ll &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(double &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (ch=='.'){
double tmp=1; ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
}
if (sign)x=-x;
}
inline void read(char *s){
char ch=nc();
for (;blank(ch);ch=nc());
if (IOerror)return;
for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
*s=0;
}
inline void read(char &c){
for (c=nc();blank(c);c=nc());
if (IOerror){c=-1;return;}
}
//getchar->read
inline void read1(int &x){
char ch;int bo=0;x=0;
for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
if (bo)x=-x;
}
inline void read1(ll &x){
char ch;int bo=0;x=0;
for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
if (bo)x=-x;
}
inline void read1(double &x){
char ch;int bo=0;x=0;
for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
if (ch=='.'){
double tmp=1;
for (ch=getchar();ch>='0'&&ch<='9';tmp/=10.0,x+=tmp*(ch-'0'),ch=getchar());
}
if (bo)x=-x;
}
inline void read1(char *s){
char ch=getchar();
for (;blank(ch);ch=getchar());
for (;!blank(ch);ch=getchar())*s++=ch;
*s=0;
}
inline void read1(char &c){for (c=getchar();blank(c);c=getchar());}
//scanf->read
inline void read2(int &x){scanf("%d",&x);}
inline void read2(ll &x){
#ifdef _WIN32
scanf("%I64d",&x);
#else
#ifdef __linux
scanf("%lld",&x);
#else
puts("error:can't recognize the system!");
#endif
#endif
}
inline void read2(double &x){scanf("%lf",&x);}
inline void read2(char *s){scanf("%s",s);}
inline void read2(char &c){scanf(" %c",&c);}
inline void readln2(char *s){gets(s);}
//fwrite->write
struct Ostream_fwrite{
char *buf,*p1,*pend;
Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
void out(char ch){
if (p1==pend){
fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
}
*p1++=ch;
}
void print(int x){
static char s[15],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1);
}
void println(int x){
static char s[15],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1); out('\n');
}
void print(ll x){
static char s[25],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1);
}
void println(ll x){
static char s[25],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1); out('\n');
}
void print(double x,int y){
static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
if (x<-1e-12)out('-'),x=-x;x*=mul[y];
ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
}
void println(double x,int y){print(x,y);out('\n');}
void print(char *s){while (*s)out(*s++);}
void println(char *s){while (*s)out(*s++);out('\n');}
void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
~Ostream_fwrite(){flush();}
}Ostream;
inline void print(int x){Ostream.print(x);}
inline void println(int x){Ostream.println(x);}
inline void print(char x){Ostream.out(x);}
inline void println(char x){Ostream.out(x);Ostream.out('\n');}
inline void print(ll x){Ostream.print(x);}
inline void println(ll x){Ostream.println(x);}
inline void print(double x,int y){Ostream.print(x,y);}
inline void println(double x,int y){Ostream.println(x,y);}
inline void print(char *s){Ostream.print(s);}
inline void println(char *s){Ostream.println(s);}
inline void println(){Ostream.out('\n');}
inline void flush(){Ostream.flush();}
//puts->write
char Out[OUT_SIZE],*o=Out;
inline void print1(int x){
static char buf[15];
char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
while(x)*p1++=x%10+'0',x/=10;
while(p1--!=buf)*o++=*p1;
}
inline void println1(int x){print1(x);*o++='\n';}
inline void print1(ll x){
static char buf[25];
char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
while(x)*p1++=x%10+'0',x/=10;
while(p1--!=buf)*o++=*p1;
}
inline void println1(ll x){print1(x);*o++='\n';}
inline void print1(char c){*o++=c;}
inline void println1(char c){*o++=c;*o++='\n';}
inline void print1(char *s){while (*s)*o++=*s++;}
inline void println1(char *s){print1(s);*o++='\n';}
inline void println1(){*o++='\n';}
inline void flush1(){if (o!=Out){if (*(o-1)=='\n')*--o=0;puts(Out);}}
struct puts_write{
~puts_write(){flush1();}
}_puts;
inline void print2(int x){printf("%d",x);}
inline void println2(int x){printf("%d\n",x);}
inline void print2(char x){printf("%c",x);}
inline void println2(char x){printf("%c\n",x);}
inline void print2(ll x){
#ifdef _WIN32
printf("%I64d",x);
#else
#ifdef __linux
printf("%lld",x);
#else
puts("error:can't recognize the system!");
#endif
#endif
}
inline void println2(ll x){print2(x);printf("\n");}
inline void println2(){printf("\n");}
#undef ll
#undef OUT_SIZE
#undef BUF_SIZE
};
using namespace fastIO;
int n,m,a[N],root[N],num;
struct node
{
int ans_p,v;
node(int ans_p=0,int v=0):ans_p(ans_p),v(v){}
}seg[N<<2],ans;
struct Node
{
int key,sz;
int ch[2],pnt;
}cho[N];
int ncnt;
void rs(int x)
{
cho[x].sz=cho[cho[x].ch[0]].sz+cho[cho[x].ch[1]].sz+1;
}
void rotate(int x)
{
int y=cho[x].pnt,k=(cho[y].ch[0]==x);
cho[y].ch[!k]=cho[x].ch[k];
cho[cho[x].ch[k]].pnt=y;
cho[x].pnt=cho[y].pnt;
cho[cho[y].pnt].ch[cho[cho[y].pnt].ch[1]==y]=x;
cho[x].ch[k]=y;
cho[y].pnt=x;
rs(y);
}
void splay(int x,int g,int col)
{
for (;cho[x].pnt!=g;rotate(x))
if (cho[cho[x].pnt].pnt!=g)
rotate((x==cho[cho[x].pnt].ch[0])==(cho[x].pnt==cho[cho[cho[x].pnt].pnt].ch[0])?cho[x].pnt:x);
rs(x);
if (!g) root[col]=x;
}
void newnode(int &x,int fa,int data,int Now)
{
x=Now?Now:(++ncnt);
cho[x].pnt=fa;
cho[x].key=data;
cho[x].sz=1;
cho[x].ch[0]=cho[x].ch[1]=0;
}
void Insert(int key,int Now,int col)
{
int x=root[col],y;
if (!x)
{
root[col]=Now?Now:(++ncnt);
cho[root[col]].ch[0]=cho[root[col]].ch[1]=cho[root[col]].pnt=0;
cho[root[col]].key=key;
cho[root[col]].sz=1;
return;
}
while(cho[x].ch[cho[x].key<key])
{
cho[x].sz++;
x=cho[x].ch[cho[x].key<key];
}
cho[x].sz++;
newnode(cho[x].ch[cho[x].key<key],x,key,Now);
splay(cho[x].ch[cho[x].key<key],0,col);
}
int searchmin(int col)
{
int x=cho[root[col]].ch[0];
while (cho[x].ch[1]) x=cho[x].ch[1];
return x;
}
int search(int key,int col)
{
if (!root[col]) return 0;
int x=root[col],y=0;
while (1)
{
if (key==cho[x].key) break;
else
if (key>cho[x].key)
{
if (cho[x].ch[1]) x=cho[x].ch[1];
else break;
}
else
{
if (cho[x].ch[0]) x=cho[x].ch[0];
else break;
}
}
y=x;
splay(x,0,col);
return y;
}
void clear(int x)
{
cho[x].ch[0]=cho[x].ch[1]=cho[x].key=cho[x].pnt=cho[x].sz=0;
}
int Erase(int key,int col)
{
if (!root[col]) return 0;
int x=search(key,col),y;
if (!x) return 0;
if (!cho[x].ch[0]&&!cho[x].ch[1])
{
root[col]=0;
return x;
}
else
if (!cho[x].ch[0])
{
root[col]=cho[x].ch[1];
cho[cho[x].ch[1]].pnt=0;
return x;
}
else
if (!cho[x].ch[1])
{
root[col]=cho[x].ch[0];
cho[cho[x].ch[0]].pnt=0;
return x;
}
y=searchmin(col);
splay(y,0,col);
cho[cho[x].ch[1]].pnt=y;
cho[y].ch[1]=cho[x].ch[1];
cho[y].pnt=0;
clear(x);
rs(y);
root[col]=y;
return x;
}
int Rank(int x,int col)
{
int Now=root[col],Ans=0,y;
while (Now)
{
y=Now;
if (cho[Now].key>x) Now=cho[Now].ch[0];
else
{
Ans+=cho[cho[Now].ch[0]].sz+1;
Now=cho[Now].ch[1];
}
}
splay(y,0,col);
return Ans;
}
node merge(node x,node y)
{
node tmp;
if (x.ans_p==y.ans_p)
tmp.ans_p=x.ans_p,tmp.v=x.v+y.v;
else
if (x.v<=y.v) tmp.ans_p=y.ans_p,tmp.v=y.v-x.v;
else tmp.ans_p=x.ans_p,tmp.v=x.v-y.v;
return tmp;
}
void build(NOW)
{
if (l==r)
{
seg[cur]=node(a[l],1);
return;
}
build(lson);
build(rson);
seg[cur]=merge(seg[lc],seg[rc]);
}
void qry(NOW,int L,int R)
{
if (L<=l&&R>=r)
{
ans=merge(ans,seg[cur]);
return;
}
if (L<=mid) qry(lson,L,R);
if (R>mid) qry(rson,L,R);
}
void ins(NOW,int x,int y)
{
if (l==r)
{
seg[cur]=node(y,1);
return;
}
if (x<=mid) ins(lson,x,y);
else ins(rson,x,y);
seg[cur]=merge(seg[lc],seg[rc]);
}
int main()
{
cho[0].sz=0,read(n),read(m);
for (int i=1;i<=n;i++) read(a[i]);
for (int i=1;i<=n;i++) Insert(i,0,a[i]);
build(Root);
for (int i=1;i<=m;i++)
{
int l,r,s,k,x,tmp;
read(l),read(r),read(s),read(k);
ans=node(0,0),qry(Root,l,r);
if (l!=1) num=Rank(r,ans.ans_p)-Rank(l-1,ans.ans_p);
else num=Rank(r,ans.ans_p);
if (num<=((r-l+1)>>1)) ans=node(s,0);
for (int j=1;j<=k;j++)
{
read(x),tmp=Erase(x,a[x]);
ins(Root,x,ans.ans_p);
Insert(x,tmp,a[x]=ans.ans_p);
}
println(ans.ans_p);
}
ans=node(0,0),qry(Root,1,n);
num=Rank(n,ans.ans_p);
if (num<=(n>>1)) ans=node(-1,0);
println(ans.ans_p);
return 0;
}
核心密码:
坑爹的积分,考场上根本想不到!!
转化一下变为贡献的形式,然后预处理前10w,后面积分(精度准的吓人)
#include <bits/stdc++.h>
#define gc getchar()
#define N 100001
#define ll long long
using namespace std;
ll n;
long double a[65][N];
ll read()
{
ll x=1;
char ch;
while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
ll s=ch-'0';
while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
return s*x;
}
long double get(long double l,long double r,int k)
{
return 1.0/(1.0-k)*pow(r,-k+1)-1.0/(1.0-k)*pow(l,-k+1);
}
int main()
{
ll T=read();
for (int i=2;i<=64;i++)
for (int j=2;j<N;j++)
a[i][j]=a[i][j-1]+pow(j,-i);
while (T--)
{
n=read();
long double ans=0;
for (ll i=2,j=4;j<=n;j<<=1,i++)
{
ll now=pow(n,1.0/i);
if (now<N) ans+=a[i][now];
else ans+=a[i][N-1]+get(N-0.5,now+0.5,i);
}
printf("%.14Lf\n",ans);
}
return 0;
}
膜法:
没做过,但据miaom和wanglichao1121说:就是建立时间树,dfs序 线段树维护,删边非常烦,使用线段树区间维护加边,删边变为多段加边。。然后维护支持撤销的带权并查集(我反正一脸懵逼)
简单的(chao nan)数学题:
狂化简+莫比乌斯
最后发现只要杜教筛mu(i)*i^2
这时候取g=id^2(g(i)=i^2)就好了
可以自己算算,有空再补过程
#include <bits/stdc++.h>
#define ll long long
#define N 6500009
using namespace std;
ll p,ans,phi[N],pri[N/8],cnt,P[N],inv[7];
bool pd[N];
ll n,m;
ll get_phi(ll x)
{
return (x<N)?phi[x]:P[m/x];
}
ll Sum(ll x)
{
return x%p*((x+1)%p)%p*((2*x+1)%p)%p*inv[6]%p;
}
void get(ll n)
{
ll t=m/n;
if (n<N||pd[t]) return;
pd[t]=1;
P[t]=n%p*((n+1)%p)%p*inv[2]%p;
P[t]=P[t]*P[t]%p;
for (ll i=2,j;i<=n;i=j+1)
{
j=n/(n/i),get(n/i);
P[t]=(P[t]-(Sum(j)-Sum(i-1)+p)%p*get_phi(n/i)%p+p)%p;
}
}
int main()
{
scanf("%lld%lld",&p,&n);
phi[1]=pd[1]=1;
inv[1]=1;
for (ll i=2;i<=6;i++) inv[i]=(p-p/i)*inv[p%i]%p;
for (ll i=2;i<N;i++)
{
if (!pd[i]) pri[++cnt]=i,phi[i]=i-1;
for (ll j=1;j<=cnt&&pri[j]*i<N;j++)
{
pd[pri[j]*i]=1;
if (i%pri[j]==0)
{
phi[pri[j]*i]=phi[i]*pri[j];
break;
}
phi[pri[j]*i]=phi[i]*(pri[j]-1);
}
}
memset(pd,0,sizeof(pd));
for (ll i=1;i<N;i++) phi[i]=(phi[i-1]+phi[i]*i%p*i%p)%p;
ll tmp=0,now,a1;
get(m=n);
for (ll i=1,j;i<=n;i=j+1)
{
j=n/(n/i);
now=tmp;
a1=(n/i)%p*((n/i+1)%p)%p*inv[2]%p;
ans=(ans+a1*a1%p*((tmp=get_phi(j))-now+p)%p)%p;
}
printf("%lld",(ans+p)%p);
return 0;
}