HAOI2012 容易题

题目链接:戳我

就是乘法分配律。。。

但是一定要注意判重+判断输入的值是否都在n里面+谨防爆int!!!!

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#define MAXN 1000010
#define mod 1000000007
using namespace std;
int n,m,k,cnt;
long long tot,ans;
map<int,int>fw;
map<pair<int,int>,int>done;
struct Node{int pos,sum;}node[MAXN];
inline bool cmp(struct Node x,struct Node y){return x.pos<y.pos;}
inline long long fpow(int x,int y)
{
    long long cur_ans=1;
    x%=mod;
    while(y)
    {
        if(y&1) cur_ans=1ll*cur_ans*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return cur_ans;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    freopen("ce.out","w",stdout);
    #endif
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=k;i++)
    {
        scanf("%d%d",&node[i].pos,&node[i].sum);
        if(done[make_pair(node[i].pos,node[i].sum)]||node[i].sum>n) 
            {i--,k--;continue;}
        if(!fw[node[i].pos]) cnt++;//cnt表示有限制的位置的个数
        fw[node[i].pos]=1;
        done[make_pair(node[i].pos,node[i].sum)]=1;
    }
    sort(&node[1],&node[k+1],cmp);
    tot=(1ll*(1+n)*n/2)%mod;
    ans=fpow(tot,m-cnt)%mod;
    if(cnt==1)
    {
        long long cur_sum=tot;
        for(int i=1;i<=k;i++)
            cur_sum=(1ll*cur_sum+mod-node[i].sum)%mod;
        ans=1ll*cur_sum*ans%mod;
    }
    else
    {
        long long cur_sum=0;
        for(int i=1;i<=k+1;i++)
        {
            if(i!=1&&node[i].pos!=node[i-1].pos)
            {
                ans=1ll*ans*(1ll*tot+mod-cur_sum)%mod;
                cur_sum=node[i].sum;
            }
            else cur_sum=(1ll*cur_sum+node[i].sum)%mod;
        }
    }
    printf("%lld\n",ans%mod);
    return 0;
}
上一篇:HAOI2012 道路


下一篇:P2505 [HAOI2012]道路