码迷,mamicode.com
首页 > 其他好文 > 详细

【学长虐学弟欢乐赛系列】Round2

时间:2015-03-01 17:08:12      阅读:307      评论:0      收藏:0      [点我收藏+]

标签:随便搞搞

第二套题
出题人:Lavender
神犇地址:Lavender学姐的blog
试题下载地址
数据下载地址
T1 matrix
**主要题干:**Neo 会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩
和用鼠标乱点之类的事,甚至会一脚踢掉电源……这些事有的会让做
这件事的这段时间内 CPU 使用率增加或减少一个值;有的事还会直
接让 CPU 使用率变为一个值。
当然 Neo 会询问:在之前给出的事件影响下, CPU 在某段时间内,
使用率最高是多少。有时候 Neo 还会好奇地询问,在某段时间内 CPU
曾经的最高使用率是多少。
为了使计算精确,使用率不用百分比而用一个整数表示。 不保
证 Neo 的事件列表出了莫名的问题,使得使用率为负……………… (也
就是说序列中的数可能为负数)
Q X Y:询问从 X 到 Y 这段时间内 CPU 最高使用率
A X Y:询问从 X 到 Y 这段时间内之前列出的事件使 CPU 达到过的最高
使用率
P X Y Z:列出一个事件这个事件使得从 X 到 Y 这段时间内 CPU 使用率增
加 Z
C X Y Z:列出一个事件这个事件使得从 X 到 Y 这段时间内 CPU 使用率变
为 Z
详情请见COGS1904CPU监控

姿势奇怪的线段树
5小时全都拿来写这一个题
别的题连暴力都没写
甚至这个题暴力也没写
结果最后还是挂了
不想说什么了…
虽然感觉所有题就会第一题标算但是还是没写出来
直接贴代码

//std by Lavender
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define maxn 100001
#define inf -1<<31 
using namespace std;
struct node{int maxx,pmaxx,add,padd,c,pc;} a[maxn*4];
int b[maxn],n,m,l,r,z;char st[5];
inline int read()
{
    char c=getchar();int bj=1,result=0;
    while (c!=‘-‘&&!(c<=‘9‘&&c>=‘0‘)) c=getchar();
    if (c==‘-‘) bj=-1,c=getchar();
    while (c<=‘9‘&&c>=‘0‘) result=result*10+c-‘0‘,c=getchar();
    return result*bj;
}
inline void update(int now)
{
    a[now].maxx=max(a[now*2].maxx,a[now*2+1].maxx);
    a[now].pmaxx=max(a[now*2].pmaxx,a[now*2+1].pmaxx);
}
inline void build(int now,int left,int right)
{
    a[now].c=a[now].pc=inf;
    a[now].add=a[now].padd=0;
    if (left==right) {a[now].maxx=a[now].pmaxx=b[left];return;}
    int mid=(left+right)>>1;
    build(now*2,left,mid);
    build(now*2+1,mid+1,right);
    update(now);
}
inline void pushdown(int now,int left,int right)
{
    for (int i=0;i<=1;i++)
    {
        int k=now*2+i;
        a[k].pmaxx=max(max(a[k].pmaxx,a[k].maxx+a[now].padd),a[now].pc);
        if(a[k].c==inf)
        a[k].padd=max(a[k].padd,a[k].add+a[now].padd);//!
            else a[k].pc=max(a[k].c+a[now].padd,a[k].pc);
        if (a[now].add)
        {
            if (a[k].c!=inf) a[k].c+=a[now].add;
                else a[k].add+=a[now].add;
            a[k].maxx+=a[now].add;
        }
        if (a[now].c!=inf)
        {
            a[k].maxx=a[k].c=a[now].c;
            a[k].add=0;
        }
        a[k].pc=max(a[k].pc,a[now].pc);
        a[k].pc=max(a[k].pc,a[k].c);
        a[k].padd=max(a[k].padd,a[k].add);
    }
    a[now].c=a[now].pc=inf;a[now].add=a[now].padd=0;
}
inline int query(int now,int left,int right)
{
    if (left!=right) pushdown(now,left,right);
    if (l<=left&&r>=right)
        return st[0]==‘Q‘?a[now].maxx:a[now].pmaxx;
    int mid=(left+right)>>1,result=inf;
    if (l<=mid) result=query(now*2,left,mid);
    if (r>mid) result=max(result,query(now*2+1,mid+1,right));
    return result;
}
inline void  change(int now,int left,int right)
{
    if (left!=right) pushdown(now,left,right);
    if (l<=left&&r>=right)
    {
        if (st[0]==‘P‘)
        {
            a[now].add+=z;a[now].padd+=z;
            a[now].maxx+=z; 
        }
        else a[now].pc=a[now].maxx=a[now].c=z;
        a[now].pmaxx=max(a[now].pmaxx,a[now].maxx);
        return;
    }
    int mid=(left+right)>>1;
    if (l<=mid) change(now*2,left,mid);
    if (mid<r) change(now*2+1,mid+1,right);
    update(now);
}
int main()
{
    freopen("matrix.in","r",stdin);
    freopen("matrix.out","w",stdout);   
    n=read();
    for (int i=1;i<=n;i++) b[i]=read();
    build(1,1,n);
    m=read(); 
    while (m--)
    {
        scanf("%s",st);l=read();r=read();
        if (st[0]==‘Q‘||st[0]==‘A‘)     printf("%d\n",query(1,1,n));
        if (st[0]==‘P‘||st[0]==‘C‘)
        {
            z=read();
            change(1,1,n);
        }
    }
}

T2
主要题干:在未来, 地球已经不适合人类居住,唯有通过虫洞进入未知的世
界寻找新的宜居星球。机智幽默的机器人 tars 勇敢的穿越了黑洞得到
了可以拯救人类的重要数据。 这些数据是由二进制存储的。不幸的是,
五维空间生物为了考验库珀,要求 tars 将数据加密。加密后的数据仍
旧是一组 n 个二进制数。 定义

//std by Lavender
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath> 
#define  LL long long
using namespace std;
const int  maxn=12010,maxb=120;
const int  maxbit=31;
const int  maxm=12010*32+10;
int  a[maxb][maxn],root[maxn],b[maxb],size[maxm],son[maxm][2],sum[maxn];
int  block,tot=0,n,m,bn;
inline int  query(int  left,int  right,int  value)
{
    int  ans=0;
    left=root[left+1];right=root[right+1];
    for (int  i=maxbit;i>=1;i--)
    {
        int  k=(value>>(i-1)&1)^1;
        if(size[son[right][k]]-size[son[left][k]]==0) k^=1;
            else ans+=1<<(i-1);
        right=son[right][k];left=son[left][k]; 
    }
    return ans;
}
inline void add(int  now,int  value)
{
    int  old=root[now-1];root[now]=++tot;now=root[now];
    for (int  i=maxbit;i>=1;i--)
    {
        int  k=(value>>(i-1))&1;
        size[now]=size[old]+1;
        son[now][k^1]=son[old][k^1];
        son[now][k]=++tot;
        now=son[now][k];old=son[old][k];
    }size[now]=size[old]+1;
}
inline int  read()
{
    char c=getchar();int  bj=1,result=0;
    while (c!=‘-‘&&!(c<=‘9‘&&c>=‘0‘)) c=getchar();
    if (c==‘-‘) bj=-1,c=getchar();
    while (c<=‘9‘&&c>=‘0‘) result=result*10+c-‘0‘,c=getchar();
    return result*bj;
}
inline int  pos(int  x)
{
    return (x-1)/block+1;
}
int main()
{
    int  i,j,k,lastans=0,l,p,x,y,ans,bx,by,tx,ty;
    freopen("intersteller.in","r",stdin);
    freopen("intersteller.out","w",stdout);
    n=read();m=read();
    add(1,0); 
    for (i=1;i<=n;i++)
    {
        sum[i]=sum[i-1]^read();
        add(i+1,sum[i]);
    }
    block=floor(sqrt(n)); bn=ceil(n/(double)block);
    for (i=1;i<=bn;i++) b[i]=(i-1)*block+1;
    for (i=1;i<=bn;i++)
        for (a[i][b[i]-1]=1<<31,j=b[i];j<=n;j++)
            a[i][j]=max(a[i][j-1],query(b[i]-2,j-1,sum[j]));
    while (m--)
    {
        tx=read();ty=read(); 
        x=(int)((tx+(LL)lastans)%n+1);
        y=(int)((ty+(LL)lastans)%n+1);
        if (x>y) swap(x,y);
        bx=pos(x);by=pos(y);
        ans=a[bx+1][y];
        for (i=x;i<=min(bx*block,y);i++)
            ans=max(ans,query(i-1,y,sum[i-1]));
        lastans=ans;
        printf("%d\n",(int)ans);
    }   
}

T3 Lord
这是官方防AK题= =
完全不会题解也听不懂

主要题干: Legolas 不仅颜好, 而且是一只聪明的精灵。他在做一道题 w
一个数 n 被称为半完美数当且仅当存在三个整数 a、 b、 c,使得
b>1,1c<a,n=c×ab.对于给定的 L,R,求区间[L,R]中半完美数的个数。
相信不等他开口求助你就能把他做出来.

请直接暴力枚举或者搜索骗分.(我没写但是别人写了能40分= =)
官方题解太长了QAQ各种化简什么的完全不会OTZ
还用到了莫比乌斯反演QAQ
官方题解请看学姐的blog…
标程能看懂请随便看
看懂之后请务必在联系蒟蒻 求教ingQAQ

//std by Lavender
#include <cstdio>
#include <vector>
#include <cstring>
#include<iostream>
#define sz(c) (int)(c).size()
#define rep(i,j,k) for (int i=j;i<=k;++i)

using namespace std;

typedef long long LL;

const LL N=(LL)1e18;
const int N2=1e9,N3=1e6,N4=31622;

LL gcd(LL a,LL b){
    return b?gcd(b,a%b):a;
}

int sqrt2(LL x){
    int l=1,r=N2,ans=-1;
    while (l<=r){
        int mid=l+r>>1;
        if ((LL)mid*mid<=x) ans=mid,l=mid+1;
        else r=mid-1;
    }
    return ans;
}

int sqrt3(LL x){
    int l=1,r=N3,ans=-1;
    while (l<=r){
        int mid=l+r>>1;
        if ((LL)mid*mid*mid<=x) ans=mid,l=mid+1;
        else r=mid-1;
    }
    return ans;
}

class SemiPerfectPower{
    private:
        int *cnt[N4+10];
        vector<int> fac[N4+10];
        bool p2[N3+10],p3[N4+10];
        LL calc(LL n){
            LL ans=0;
            for (int c=1;(LL)c*c*c<n;++c)
                if (p2[c]) ans+=sqrt2(n/c)-c;
        //  cout<<ans<<endl;
            for (int b=1;(LL)b*b*b*b<n;++b)
                if (p3[b])
                    for (int k=1;k*k*k<=b;++k){
                        int g=gcd(b,k*k),b_=b/g,k_=k*k/g;
                        if (!p2[b_]) continue;
                        int miny=b,maxy=sqrt3(n/b),size=sz(fac[b_]),all=1<<size;
                        rep(i,0,all-1){
                            int d=1,mu=1;
                            rep(j,0,size-1) if (i>>j&1) d*=fac[b_][j],mu*=-1;
                            ans+=mu*(cnt[d][maxy/k_/d]-cnt[d][miny/k_/d]);
                        }
                    }
            return ans;
        }
    public:
        SemiPerfectPower(){
            memset(p2+1,true,sizeof p2);
            memset(p3+1,true,sizeof p3);
            for (int i=2;i*i<=N3;++i){
                int t=i*i;
                for (int j=t;j<=N3;j+=t) p2[j]=false;
            }
            for (int i=2;i*i*i<=N4;++i){
                int t=i*i*i;
                for (int j=t;j<=N4;j+=t) p3[j]=false;
            }
            rep(i,1,N4){
                int l=N3/i;
                cnt[i]=new int[l+1];
                cnt[i][0]=0;
                rep(j,1,l) cnt[i][j]=cnt[i][j-1]+p2[i*j];
            }
            rep(i,2,N4) if (fac[i].empty())
                for (int j=i;j<=N4;j+=i) fac[j].push_back(i);
        }
        LL count(LL l,LL r){
            return calc(r)-calc(l-1);
        }
}solve;
int main(){
    freopen("lord.in","r",stdin);
    freopen("lord.out","w",stdout);
    LL l,r;
    scanf("%I64d%I64d",&l,&r);
    printf("%I64d\n",solve.count(l,r));
    return 0;
}

这次比赛告诉我们不要老是盯着一个题搞标算请老老实实写暴力QAQ
我以后一定要好好写暴力QAQ

【学长虐学弟欢乐赛系列】Round2

标签:随便搞搞

原文地址:http://blog.csdn.net/creationaugust/article/details/44003525

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!