【Training Contest】2016.03.08

aw。。。这好像是停课以来第一次考试哎。。。蒟蒻滚粗啦

T1.变幻莫测的数列

T1-1
T1-2

迷之卡常QAQ;不过窝竟然卡了90分。。。憋人都卡了85。。好神奇啊

听说卡常技巧。。。计算时暴力int转longlong,用int记录。。。反复定义的变量改全局。。。读入优化QAQ

考试时候写了两个程序,分块和线段树。。显然线段树更快一点

分块

#include <iostream> 
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define mod 1000000007ll
#define LL long long
#define NN 500010
using namespace std;

int n,q,cnt,block,belong[NN],st[NN],x;
struct REC
{
    LL a,b;
}s[NN],c[NN];
LL ans;
char ch,chh[55];
bool f;
void readl(LL &x){
    for(ch=getchar();ch<'0'||ch>'9';ch=getchar());
    for(x=0;ch>='0';ch=getchar())x=x*10+ch-'0';
}
void read(int &x){
    for(ch=getchar();ch<'0'||ch>'9';ch=getchar());
    for(x=0;ch>='0';ch=getchar())x=x*10+ch-'0';
}
void Build(int xx)
{
    c[xx].a=1ll,c[xx].b=0ll;
    for (int j=st[xx];j<=st[xx+1]-1;++j)
        c[xx].a=(c[xx].a*s[j].a)%mod, c[xx].b=((c[xx].b*s[j].a)%mod+s[j].b)%mod;
}
int main()
{
    freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout);
    read(n), read(q);
    for (int i=1;i<=n;++i) readl(s[i].a), readl(s[i].b);
    cnt=(int) sqrt(n);
    for (int i=1;i<=n;++i) belong[i]=(i-1)/cnt+1; block=belong[n];
    block=(n-1)/cnt+1;
    for (int i=1;i<=block;++i) st[i]=(i-1)*cnt+1;
    st[block+1]=n+1;
    for (int i=1;i<=block;++i) Build(i);
    while (q--)
    {
        scanf("%s",chh);
        if (chh[0]=='Q')
        {
            read(x);
            ans=1ll;
            for (int i=1;i<belong[x];++i) ans=(ans*c[i].a%mod+c[i].b)%mod;
            for (int i=st[belong[x]];i<=x;++i) ans=(ans*s[i].a%mod+s[i].b)%mod;
            printf("%lld\n",ans);
        }
        else
            read(x), readl(s[x].a), readl(s[x].b), Build(belong[x]);
    }
    fclose(stdin); fclose(stdout);
    return 0;
}

线段树(%%%把线段树写RE的线段树大师(大雾

#include <iostream> 
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define mod 1000000007ll
#define LL long long
#define NN 500010
using namespace std;

int n,q,x;
LL ans;
struct REC
{
    int l,r,mid;
    LL a,b;
}tree[NN*6];
struct NODE
{
    LL a,b;
}s[NN];
char ch,chh[55];
void readl(LL &x){
    for(ch=getchar();ch<'0'||ch>'9';ch=getchar());
    for(x=0;ch>='0';ch=getchar())x=x*10+ch-'0';
}
void read(int &x){
    for(ch=getchar();ch<'0'||ch>'9';ch=getchar());
    for(x=0;ch>='0';ch=getchar())x=x*10+ch-'0';
}
void Build(int p,int x,int y)
{
    tree[p].l=x, tree[p].r=y, tree[p].mid=(x+y)>>1;
    if (x==y)
    {   tree[p].a=s[x].a%mod, tree[p].b=s[x].b%mod; return; }
    Build(p<<1,x,tree[p].mid), Build(p<<1|1,tree[p].mid+1,y);
    tree[p].a=tree[p<<1].a*tree[p<<1|1].a%mod;
    tree[p].b=(tree[p<<1].b*tree[p<<1|1].a%mod+tree[p<<1|1].b)%mod;
}
void Change(int p,int x)
{
    if (tree[p].l==x && tree[p].r==x) tree[p].a=s[x].a, tree[p].b=s[x].b;
    else
    {   if (x<=tree[p].mid)  Change(p<<1,x);
        else Change(p<<1|1,x);
        tree[p].a=tree[p<<1].a*tree[p<<1|1].a%mod;
        tree[p].b=(tree[p<<1].b*tree[p<<1|1].a%mod+tree[p<<1|1].b)%mod;
    }
}
void Query(int p,int x,int y)
{
    if (tree[p].l==x && tree[p].r==y) 
    {   ans=((ans*tree[p].a)%mod+tree[p].b)%mod; return;    }
    else
    {
        if (y<=tree[p].mid) Query(p<<1,x,y);
        else    Query(p<<1,x,tree[p].mid), Query(p<<1|1,tree[p].mid+1,y);
    }
}
int main()
{
    freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout);
    read(n), read(q);
    for (int i=1;i<=n;++i) readl(s[i].a), readl(s[i].b);
    Build(1,1,n);
    while (q--)
    {
        scanf("%s",chh);
        if (chh[0]=='Q')
        {
            read(x);
            if (x==0) { puts("1"); continue;} 
            ans=1ll; Query(1,1,x);
            printf("%lld\n",ans);
        }
        else
        {
            read(x), readl(s[x].a), readl(s[x].b);
            Change(1,x);
        }
    }
    fclose(stdin); fclose(stdout);
    return 0;
}

T2.微型加密系统

T2-1
T2-2

考试骗了20分滚粗走人

骗分程序(Floyd直接输出答案。。。听说两边spfa有40分

#include <iostream> 
#include <cstdio>
#include <cstring>
#include <queue>
#include <cstdlib>
using namespace std;

int n,m,x,y,a[110][110];

int main()
{
    freopen("microc.in","r",stdin); freopen("microc.out","w",stdout);
    while (scanf("%d%d",&n,&m))
    {
        if (n==0 && m==0) break;
        memset(a,0x3f,sizeof(a));
        for (int i=1;i<=m;++i) scanf("%d%d",&x,&y), a[x][y]=1;
        for (int k=1;k<=n;++k)
            for (int i=1;i<=n;++i)
                for (int j=1;j<=n;++j) a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
        if (a[1][2]==0x3f3f3f3f || a[2][1]==0x3f3f3f3f)
        {   puts("Impossible"); continue;   }
        printf("%d\n",a[1][2]+a[2][1]);
    }
    fclose(stdin); fclose(stdout);
    return 0;
}

新鲜出炉的FLOYD&SPFA

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define NN 110 
using namespace std;

int n,m,x,y,dis[NN][NN],a[NN][NN];
bool vis[NN][NN];
struct REC
{
    int x,y;
};
queue<REC> que;


int main()
{
    freopen("microc.in","r",stdin); freopen("microc.out","w",stdout);
    while (scanf("%d%d",&n,&m)>0 && n)
    {
        memset(a,0x3f,sizeof(a));
        for (int i=1;i<=n;++i) a[i][i]=0;
        for (int i=1;i<=m;++i) scanf("%d%d",&x,&y), a[x][y]=1;
        for (int k=1;k<=n;++k)
            for (int i=1;i<=n;++i)
                for (int j=1;j<=n;++j) a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
        memset(dis,0x3f,sizeof(dis));
        REC tmp,tmpp;
        tmp.x=1,tmp.y=1; dis[1][1]=1; vis[1][1]=1;
        que.push(tmp);
        while (!que.empty())
        {
            tmp=que.front(); que.pop();
            for (int i=1;i<=n;++i)
            {
                int j=(i!=tmp.x)&&(i!=tmp.y);
                if (a[tmp.x][i]==1 && dis[i][tmp.y]>dis[tmp.x][tmp.y]+j)
                {
                    dis[i][tmp.y]=dis[tmp.x][tmp.y]+j;
                    if (!vis[i][tmp.y]) vis[i][tmp.y]=1, tmpp.x=i, tmpp.y=tmp.y, que.push(tmpp);
                }
                if (a[i][tmp.y]==1 && dis[tmp.x][i]>dis[tmp.x][tmp.y]+j)
                {
                    dis[tmp.x][i]=dis[tmp.x][tmp.y]+j;
                    if (!vis[tmp.x][i]) vis[tmp.x][i]=1, tmpp.x=tmp.x, tmpp.y=i, que.push(tmpp);
                }
            }           
            if (tmp.x!=tmp.y)
            {
                if (dis[tmp.y][tmp.x]>dis[tmp.x][tmp.y]+a[tmp.x][tmp.y]-1)
                {
                    dis[tmp.y][tmp.x]=dis[tmp.x][tmp.y]+a[tmp.x][tmp.y]-1;
                    if (!vis[tmp.y][tmp.x]) vis[tmp.y][tmp.x]=1, tmpp.x=tmp.y, tmpp.y=tmp.x, que.push(tmpp);
                }
            }
            vis[tmp.x][tmp.y]=0;
        }
        if(dis[2][2]==0x3f3f3f3f) puts("Impossible");else printf("%d\n",dis[2][2]);
    }
    fclose(stdin); fclose(stdout);
    return 0;
}

T3.俄罗斯方块问题

T3-1
迷之贪心

听说有两行程序

但蒟蒻太弱了只能码线段树了

线段树

#include <iostream> 
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define MM 4000010
using namespace std;

int n,m,x,y;
struct REC
{
    int l,r,v,mid;
}tree[MM];
int ans=0;

void read(int &x)
{
    char c;for(x=0,c=getchar();c<'0'&&c>'9';c=getchar());
    for(;c>='0'&&c<='9';x=x*10+c-'0',c=getchar());
}

void Build(int p,int x,int y)
{
    tree[p].l=x, tree[p].r=y, tree[p].v=0, tree[p].mid=(x+y)>>1;
    if (x==y) return;
    Build(p<<1,x,tree[p].mid), Build(p<<1|1,tree[p].mid+1,y);   
}

void Add(int p,int x,int y)
{
    if (tree[p].l==x && tree[p].r==y) tree[p].v++;
    else
    {
        if (y<=tree[p].mid) Add(p<<1,x,y);
        else if (x>tree[p].mid) Add(p<<1|1,x,y);
        else Add(p<<1,x,tree[p].mid), Add(p<<1|1,tree[p].mid+1,y);
    }   
}

void Query(int p,int x,int y,int v)
{
    if (x==y)   {if (v+tree[p].v>ans) ans=v+tree[p].v; return;}
    Query(p<<1,x,tree[p].mid,tree[p].v+v);
    Query(p<<1|1,tree[p].mid+1,y,tree[p].v+v);
}
int main()
{
    freopen("tetris.in","r",stdin); freopen("tetris.out","w",stdout);
    read(n), read(m);
    Build(1,1,m-1);
    for(int i=1;i<=n;++i)   { read(x), read(y); Add(1,x,y-1);   }
    Query(1,1,m-1,0);
    printf("%d\n",ans);
    fclose(stdin); fclose(stdout);
    return 0;
}

迷之压行

#include<cstdio>
int b[1000010],n,m,l,r,a,t,i;
int main()
{for(scanf("%d%d",&n,&m),i=1;i<=n;i++)scanf("%d%d",&l,&r),b[l]++,b[r]--;for(i=1;i<=m;i++)a=a>(t+=b[i])?a:t;printf("%d",a);}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值