• 2018.10.29 NOIP2018模拟赛 解题报告


    得分: (70+60+0=130)(T3)来不及打了,结果爆(0)

    (T1):简单的求和(点此看题面

    原题: 【HDU4473】Exam

    这道题其实就是上面那题的弱化版,只不过把多组数据改成了单次询问。

    题解可以参考上面给出的链接。

    比赛时我没想到可以这么做,于是写了个除法分块,交上去(70)分。

    (CJJ)奆佬写了一个传说中的(cjj)筛,结果(80)(ORZ)

    代码如下:

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    LL n;
    class Class_BruteForceSolver//暴力
    {
        public:
            inline void Solve(LL x)
            {
                register LL i,j,k,lim,ans=0;
                for(i=1;i<=x;++i) for(j=1;j<=i;++j) for(k=1,lim=i/j;k<=lim;++k) if(!(i%(j*k))) ++ans;
                printf("%lld",ans);
            }
    }BruteForceSolver;
    class Class_DivideSolver//除法分块(70分)
    {
        private:
            inline LL Calc(LL x)
            {
                register LL l,r,res=0;
                for(l=1;l<=x;l=r+1) r=x/(x/l),res+=(r-l+1)*(x/l);
                return res;
            }
        public:
            inline void Solve(LL x)
            {
                register LL l,r,ans=0;
                for(l=1;l<=x;l=r+1) r=x/(x/l),ans+=(r-l+1)*Calc(x/l);
                printf("%lld",ans);
            }
    }DivideSolver;
    class Class_MathSolver//用数学方法分类讨论(AC)
    {
        public:
            inline void Solve(LL x)
            {
                register LL i,j,k,ans=0;
                for(i=1;i*i*i<=x;++i) ++ans;
                for(i=1;i*i<=x;++i) if((j=x/(i*i))>=i) ans+=3*(j-1);else ans+=3*j;
                for(i=1;i*i*i<=x;++i) for(j=i+1;j<=x;++j) if((k=x/(i*j))>=j) ans+=6*(k-j);else break;
                printf("%lld
    ",ans);
            }
    }MathSolver;
    int main()
    {
        return scanf("%lld",&n),MathSolver.Solve(n),0;
    }
    

    (T2):奇妙的数列(点此看题面

    被卡在了(60)分。

    听说正解是线段树,但不知道如何维护信息,而且没有发题解,所以就没改了。

    代码略。

    (T3):树上的路径(点此看题面

    原题: 【BZOJ4458】GTY的OJ

    具体做法可直接参考上面的链接,这里就不详细解释了。

    代码如下:

    #include<bits/stdc++.h>
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define ten(x) (((x)<<3)+((x)<<1))
    #define LL long long
    #define N 500000
    #define INF 1e18
    using namespace std;
    int n,m,L,R;
    class FIO
    {
        private:
            #define Fsize 100000
            #define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
            #define pc(ch) (putchar(ch))
            int f,Top;char ch,*A,*B,Fin[Fsize],Stack[Fsize];
        public:
            inline void read(int &x) {x=0,f=1;while(!isdigit(ch=tc())) f=ch^'-'?1:-1;while(x=ten(x)+(ch&15),isdigit(ch=tc()));x*=f;}
            inline void write(LL x) {if(x<0) pc('-'),x=-x;if(!x) return (void)(pc('0'));while(x) Stack[++Top]=x%10+48,x/=10;while(Top) pc(Stack[Top--]);}
    }F;
    class Class_RmqSolver
    {
        private:
            #define LogN 20
        public:
            int fa[N+5][LogN],sum[N+5],Depth[N+5];
        private:
            struct key//存储每一个元素的信息
            {
                int pos,l,r,k,val;//pos表示起点,l,r存储可选择的区间,k存储当前选择的终点,val存储当前答案
                key(int x=0,int y=0,int z=0,int w=0,int v=0):pos(x),l(y),r(z),k(w),val(v){}
                inline friend bool operator < (key x,key y) {return x.val<y.val;}
            };
            priority_queue<key> q;//用一个堆进行维护 
            struct RMQ_data//RMQ求最小值
            {
                int MinPos,MinVal;
                RMQ_data(int x=0,int y=0):MinPos(x),MinVal(y){}
                inline friend bool operator < (RMQ_data x,RMQ_data y) {return x.MinVal<y.MinVal;}
            }RMQ[N+5][LogN];
            inline void Init() {for(register int i,j=1;j<LogN;++j) for(i=1;i<=n;++i) fa[i][j]=fa[fa[i][j-1]][j-1],RMQ[i][j]=min(RMQ[i][j-1],RMQ[fa[i][j-1]][j-1]);}//初始化
            inline int getfa(int x,int dep)//找父亲
            {
                for(register int i=0;i<LogN;++i) if(dep&(1<<i)) x=fa[x][i];
                return x;
            }
            inline RMQ_data get_min(int l,int r)//求最小值
            {
                register int i;register RMQ_data res=RMQ[l][0];
                for(i=LogN-1;i>=0;--i) if(Depth[fa[r][i]]>=Depth[l]) res=min(res,RMQ[r][i]),r=fa[r][i];
                return res;
            }
        public:
            inline void Solve()
            {
                register int i,t;register LL ans=0;register RMQ_data s;register key now;
                for(i=1;i<=n;++i) F.read(fa[i][0]),Depth[i]=Depth[fa[i][0]]+1;//初始化
                for(i=1;i<=n;++i) F.read(sum[i]),sum[i]+=sum[fa[i][0]],RMQ[i][0]=RMQ_data(i,sum[fa[i][0]]);//统计前缀和+初始化(这样可以不用DFS)
                for(Init(),F.read(m),F.read(L),F.read(R),i=1;i<=n;++i) if(Depth[i]>=L) t=min(R,Depth[i]),s=get_min(getfa(i,t-1),getfa(i,L-1)),q.push(key(i,getfa(i,t-1),getfa(i,L-1),s.MinPos,sum[i]-s.MinVal));//预处理把元素扔入堆中
                while(m--)
                {
                    now=q.top(),q.pop(),ans+=now.val;//取出堆中元素,统计答案,然后拆成两半重新扔入堆中
                    if(Depth[now.l]<Depth[now.k]) t=getfa(now.pos,Depth[now.pos]-Depth[now.k]+1),s=get_min(now.l,t),q.push(key(now.pos,now.l,t,s.MinPos,sum[now.pos]-s.MinVal));
                    if(Depth[now.r]>Depth[now.k]) t=getfa(now.pos,Depth[now.pos]-Depth[now.k]-1),s=get_min(t,now.r),q.push(key(now.pos,t,now.r,s.MinPos,sum[now.pos]-s.MinVal));
                }
                F.write(ans);//输出答案
            }
    }RmqSolver;
    int main()
    {
        return F.read(n),RmqSolver.Solve(),0;
    }
    
  • 相关阅读:
    CSS 实现图片灰度效果
    有关楼层滚动且对应楼层Nav导航高亮显示
    本地上传图片预览效果
    gulp.js 的安装以及使用
    ReactJS -- 初学入门
    ie8下jquery改变PNG的opacity出现黑边
    数据库操作 (4-3)
    Python之协程 (4-2)
    python 之 线程 3-29
    Python之 并发编程(3-19)
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Contest20181029.html
Copyright © 2020-2023  润新知