zoukankan      html  css  js  c++  java
  • [codechef MEXDIV]Mex division

    题目链接:https://vjudge.net/contest/171650#problem/I

    直接用set+dp水过去了。。。

    /*
    设dp[i]表示前i个做划分满足条件的方案数
    有一个显然的转移方程dp[i]=sigma(dp[j])  t<=j<=i-1
    其中t是满足mex(a[t..i-1])<=k的最小的t 
    然后我们现在是想得到,对于每个位置这个t是多少,如果知道了这个,就可以很容易的转移了
    
    首先,考虑,如果k>n,那么不管怎么选,都是会满足条件的啊!(就算把所有的数都选出来,mex也就是k吧)
    所以对于k>n,直接输出2^(n-1)
    当然k=0的时候特判一下,这样每个i对应的t都是存在的,至少有一个i 现在考虑k<=n的情况,直接用一个multiset记录[1,k]里的数的出现情况 首先,把[0,k]全部都放进multiset,遇到一个新的数,就erase,查询集合里最小的数就是mex 假设现在想得到第i个位置的t,上次求得的i-1对应的t是t' 那么如果a[i]已经在集合中被删去了,那这次对应的肯定还是t' 如果a[i]没有从集合中删去,就把a[i]从集合中删去(当然,如果a[i]>k直接不用管) 考虑到随着i的增大,t肯定是往右走的 如果删去以后集合是空集了,那t'就需要右移了,直到出现一个[0,k]之间的,并且在a[t+1..i]没有出现过的数 是否出现过,只需要记一个右边第一个跟它相等的数就可以了
    */ #include<bits/stdc++.h> using namespace std; const int maxn=500005; int a[maxn]; int t[maxn]; int e[maxn]; long long dp[maxn]; long long predp[maxn]; pair<int,int> p[maxn]; set<int> S; const long long md=1000000007; long long fp(long long a,long long k) { long long res=1; a%=md; while(k) { if(k&1)res=res*a%md; a=a*a%md; k>>=1; } return res; } int main() { int n,k; scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) scanf("%d",&a[i]); if (k>n) { printf("%lld",fp(2,n-1)); return 0; } if (k==0) { bool yl=false; for (int i=1;i<=n;i++) { if (a[i]==0) { yl=true; break; } } if (yl) printf("0 "); else printf("%lld",fp(2,n-1)); return 0; } S.clear(); for (int i=0;i<=k;i++) S.insert(i); for (int i=1;i<=n;i++) { p[i].first=a[i]; p[i].second=i; } sort(p+1,p+1+n); p[n+1].first=-1; for (int i=1;i<=n;i++) { if (p[i+1].first==p[i].first) e[p[i].second]=p[i+1].second; else e[p[i].second]=-1; } int now=1; t[1]=1; if (a[1]<=k) S.erase(a[1]); for (int i=2;i<=n;i++) { if (a[i]>k || !S.count(a[i])) t[i]=t[i-1]; else { S.erase(a[i]); while (S.empty()) { if (a[now]<=k && (e[now]==-1||e[now]>i)) { S.insert(a[now]); } now++; } t[i]=now; } } dp[0]=1; predp[0]=0; predp[1]=1; for (int i=1;i<=n;i++) { // dp[t[i]-1]...dp[i-1] dp[i]=((predp[i]-predp[t[i]-1])%md+md)%md; predp[i+1]=(predp[i]+dp[i])%md; } printf("%lld ",dp[n]); return 0; }
  • 相关阅读:
    CSLA.Net 3.0.5 项目管理示例 业务基类 Project.cs
    为什么我要写博客
    LINQ 标准的查询操作符 过滤 where、index1、OfType
    LINQ 概述和演变
    sl中几个简单变量的获取
    Rails存储库从SVN转向Git
    showcase测试界面
    Silverlight读取xml
    向silverlight传递自定义参数
    RadRails1.0降临——增加Profiler、CallGraph Analyzer和Rails Shell等新特性
  • 原文地址:https://www.cnblogs.com/acmsong/p/7214278.html
Copyright © 2011-2022 走看看