洛谷5月月赛R1题解报告

来源:互联网 发布:错生网络剧 编辑:程序博客网 时间:2024/05/01 06:43

签到题:

这也算签到题!!!(想了我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,rusing 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;elseif (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 longusing 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 6500009using 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;}