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

9.27NOIP模拟题

时间:2017-09-27 21:47:13      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:tchar   两种   blog   颜色   gets   upd   排列   color   个数   

NOIP 模拟测试

 

1 任务安排


manage.in/.out/.cpp
1.1 问题描述
你有 N 个工作,同一时刻只能做一个任务, 其中每个工作有其所需时
间, 及完成的 Deadline(截止时间), 问要完成所有工作, 最迟要从什么时候开
始。
你最早可以从时间 0 开始工作。
1.2 输入格式
第一行一个整数 N,表示任务数量
接下来 n 行,每行两个整数,T i ,S i ,分别表示该任务的持续时间和截
止时间。
1.3 输出格式
输出一个整数,表示最晚的开始时间,如果不能完成,输出-1。
1.4 样例输入
4
3 5
8 14
5 20
1 16
1.5 样例输出
2
1.6 数据规模及约定
对于 40% 的数据,N <= 20
对于 60% 的数据,N <= 1000
对于 100% 的数据,1<= N <= 100000
1<= T i <= 100000
1<= S i <= 1000000

 

/*
贪心遇到不合法的统计答案
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define N 100007

using namespace std;
int n,ans,tot;
struct node
{
    int Ti,Si;
    bool operator < (const node &x)const{
            return Si<x.Si;
    }
}a[N];

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>9||c<0){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}

int main()
{
    freopen("manage.in","r",stdin);
    freopen("manage.out","w",stdout);
    int x,y;
    n=read();
    for(int i=1;i<=n;i++)
    {
        x=read();y=read();
        a[i].Ti=x;a[i].Si=y;
    }
    sort(a+1,a+n+1);
    tot=0;int flag=0;ans=0x3f3f3f3f;
    for(int i=1;i<=n;i++)
    {
        if(tot+a[i].Ti>a[i].Si)
        {
            flag=1;break;
        }
        tot+=a[i].Ti;
        ans=min(ans,a[i].Si-tot);
    }
    if(flag) printf("-1\n");
    else printf("%d\n",ans);
    fclose(stdin);fclose(stdout);
    return 0;
}

 


2 小 a 的强迫症
qiang.in/.out/.cpp
2.1 问题描述
小 a 是一名强迫症患者,现在他要给一群带颜色的珠子排成一列,现在
有 N 种颜色,其中第 i 种颜色的柱子有 num(i) 个。要求排列中第 i 种颜色
珠子的最后一个珠子,一定要排在第 i+1 种颜色的最后一个珠子之前。问
有多少种排列珠子的方案。
2.2 输入格式
第一行一个整数 N,表示珠子颜色数量
第二行 N 个整数,分别表示每种珠子的颜色数量
2.3 输出格式
排列方案数,对 998244353 取余
2.4 样例输入
3
2 2 1
2.5 样例输出
3
2.6 数据规模及约定
共 3 种排列方案:
1 2 1 2 3
1 1 2 2 3
2 1 1 2 3
对于 40% 的数据,所有珠子数量和小于 15
对于 80% 的数据,N <= 1000,所有珠子数量和小于 5000
对于 100% 的数据,N <= 100000,所有珠子数量和小于 500000

/*
又是组合数取模问题。开始dp写的,写wa了......
sum[i]为前缀和,num[i]为i颜色的数量
那么i这种颜色对答案的贡献就是C(sum[i]-1,num[i]-1)%mod;
因为i的最后一个不能放到i+1最后一个的前面,所以要减一
分步乘法原理。 
*/
#include<iostream>
#include<cstdio>
#include<cstring>

#define N 1000007
#define mod 998244353
#define ll long long

using namespace std;
ll n,m,ans,cnt;
ll f[N]={1,1},fac[N]={1,1},inv[N]={1,1};
ll num[N],sum[N];

inline ll read()
{
    ll x=0,f=1;char c=getchar();
    while(c>9||c<0){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}

void init()
{
    for(int i=2;i<=N;i++)
    {
        fac[i]=(fac[i-1]%mod*i%mod)%mod;
        f[i]=(mod-mod/i)*f[mod%i]%mod;
        inv[i]=inv[i-1]*f[i]%mod;
    }
}

ll C(int a,int b)
{
    if(a<b) return 1;
    return fac[a]%mod*inv[b]%mod*inv[a-b]%mod;
}

int main()
{
    freopen("qiang.in","r",stdin);
    freopen("qiang.out","w",stdout);
    n=read();
    for(int i=1;i<=n;i++) 
      num[i]=read(),sum[i]=sum[i-1]+num[i];
    init();ans=1;
    for(int i=2;i<=n;i++)
    {
        ans=(ans%mod*C(sum[i]-1,num[i]-1)%mod)%mod;
        ans%=mod;
    }
    printf("%I64d\n",ans%mod);
    fclose(stdin);fclose(stdout);
    return 0;
}

 


3 函数求和
sum.in/.out/.cpp
3.1 问题描述
你有一个含 N 个数字的数组 A,元素标号 1 到 N,同时他也有 N 个函
数,也标号 1 到 N。
第 i 个函数会返回数组中标号 L i 和 R i 之间的元素的和。
现在有以下两种询问:
1 x y 将数组的第 x 个元素修改为 y。
2 m n 询问标号在 m 和 n 之间的函数的值的和。
3.2 输入格式
输入数据第一行包含一个整数 N,表示数组的长度和函数的数量。
接下来的一行包含 N 个整数,表示数组中的元素 A i 。
接下来的 N 行,每行包含两个整数 L i ,R i ,表示一个函数。
接下来一行包含一个整数 Q,表示询问次数。
下面 Q 行,每行一个询问,格式见题目描述。
3.3 输出格式
对于每个第 2 类询问,输出相应的答案。
3.4 样例输入
5
1 2 3 4 5
1 3
2 5
4 5
3 5
1 2
4
2 1 4
1 3 7
2 1 4
2 3 5
4
3.5 样例输出
41
53
28
3.6 数据规模及约定
对于前 20% 的数据: N ≤ 1000,Q ≤ 1000
对于另外 30% 的数据: R i − L i ≤ 10, 所有的 x 各不相同
对于 100% 的数据: 1 ≤ N ≤ 10 5 , 1 ≤ L i ≤ R i ≤ N, 1 ≤ x ≤ N,
1 ≤ m ≤ n ≤ N, 1 ≤ A i ,y ≤ 10 9 , 1 ≤ Q ≤ 10 5

 

/*
题目来源 codechef NOV14.FNCS Chef and Churu
80分 黔驴技穷了 比着std写的 std不知为何 0分啊我也很绝望。
对于每个fi,可以直接使用树状数组求出。
所以我们可以使用分块,中间的直接用块的答案,边上的用树状数组。
首先我们进行预处理,记录第i块中每个编号的个数,这里用前缀和,并求出每个块的和。
对于修改操作1 x y,我们要维护树状数组和块状数组。
树状数组:直接维护。
块状数组:找到每个块中x的个数,这块的sum加上x*(y-a[x])。
最后把a[x]赋成y。
对于查询操作2 x y。
中间的块我们直接用块状数组的答案,O(√n)。
边上的两块我们用树状数组暴力求所有的f[i],O(√n log n)。
所以总的时间复杂度为O(n √n log n)。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>

#define ll long long
#define N 100007
#define S 400

using namespace std;
int n,m,unit,num;
int fl[N],fr[N],a[N];
int cnt[S][N];
ll ta[N],sumb[S];

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>9||c<0){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}

inline int lowbit(int x){return x&-x;}

inline void ins(int i,int add)
{
    for(;i<=n;i+=lowbit(i)) ta[i]+=add;
}

inline void update(int x,int y)
{
    ins(x,y-a[x]);
    for(int i=1;i<=num;i++) sumb[i]+=(ll)cnt[i][x]*(y-a[x]);
    a[x]=y;
}

inline ll getsum(int i)
{
    ll sum=0;
    for(;i;i-=lowbit(i)) sum+=ta[i];
    return sum;
}

ll query(int l,int r)
{
    int lblock=(l-1)/unit+1,rblock=(r-1)/unit+1;ll sum=0;
    if(lblock==rblock)
      for(int i=l;i<=r;i++)
        sum+=getsum(fr[i])-getsum(fl[i]-1);
    else
    {
        for(int i=lblock+1;i<=rblock-1;i++) sum+=sumb[i];
        for(int i=l;i<=lblock*unit;i++) sum+=getsum(fr[i])-getsum(fl[i]-1);
        for(int i=(rblock-1)*unit+1;i<=r;i++) sum+=getsum(fr[i])-getsum(fl[i]-1);
    }return sum;
}

int main()
{
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=n;i++) fl[i]=read(),fr[i]=read();
    for(int i=1;i<=n;i++) ins(i,a[i]);
    
    int nowblock=0;
    unit=(int)sqrt(n),num=unit+(unit*unit!=n);
    for(int i=1;i<=n;i++)
    {
        if(i%unit==1) nowblock++;
        cnt[nowblock][fl[i]]++;
        cnt[nowblock][fr[i]+1]--;
    }
    for(int i=1;i<=num;i++)
      for(int j=1;j<=n;j++)
      {
            cnt[i][j]+=cnt[i][j-1];
            sumb[i]+=(ll) cnt[i][j]*a[j];
      }
      
    int k,x,y;
    m=read();
    for(int i=1;i<=m;i++)
    {
        k=read();x=read();y=read();
        if(k==1) update(x,y);
        else printf("%I64d\n",query(x,y));
    }
    fclose(stdin);fclose(stdout);
    return 0;
} 

 

9.27NOIP模拟题

标签:tchar   两种   blog   颜色   gets   upd   排列   color   个数   

原文地址:http://www.cnblogs.com/L-Memory/p/7604031.html

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