洛谷5月月赛R1题解报告

签到题:

这也算签到题!!!(想了我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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值