FZU2236 第十四个目标 (树状数组+离散化)
2018-01-29 16:37
381 查看
题目传送门:点击打开链接
Problem H 第十四个目标
Accept: 44 Submit: 170
目暮警官、妃英里、阿笠博士等人接连遭到不明身份之人的暗算,柯南追踪伤害阿笠博士的凶手,根据几起案件现场留下的线索发现凶手按照扑克牌的顺序行凶。在经过一系列的推理后,柯南发现受害者的名字均包含扑克牌的数值,且扑克牌的大小是严格递增的,此外遇害者与毛利小五郎有关。
为了避免下一个遇害者的出现,柯南将可能遭到暗算的人中的数字按关联程度排列了出来,即顺序不可改变。柯南需要知道共有多少种可能结果,满足受害人名字出现的数字严格递增,但是他柯南要找出关键的证据所在,所以这个任务就交给你了。
(如果你看不懂上面在说什么,这题是求一个数列中严格递增子序列的个数。比如数列(1,3,2)的严格递增子序列有(1)、(3)、(2)、(1,3)、(1,2),共5个。长得一样的但是位置不同的算不同的子序列,比如数列(3,3)的答案是2。)
多组数据(<=10),处理到EOF。
第一行输入正整数N(N≤100 000),表示共有N个人。
第二行共有N个整数Ai(1≤Ai≤10^9),表示第i个人名字中的数字。
每组数据输出一个整数,表示所有可能的结果。由于结果可能较大,对1 000 000 007取模后输出。
31 3 2
5
2016福州大学第十三届程序设计竞赛
好题一枚,了解了离散化。
题意是求出每个i值对应的可以到达的严格递增子序列,然后从n往下来加一个和就好了。n就代表了前边所有的结果的和。
因为每一种都情况都用树状数组到了n。
所以离散化 然后树状数组
#include<stdio.h>
#include<iostream>
#include <algorithm>
#include<string.h>
#include<vector>
#include<math.h>
#include<queue>
#include<deque>
#include<map>
#include<set>
#define ll long long
#define INF 0x3f3f3f3f
const int mod = 1e9+7;
using namespace std;
int KGCD(int a,int b){if(a==0)return b;if(b==0)return a;if(~a&1){ if(b&1) return KGCD(a>>1,b);else return KGCD(a>>1,b>>1) <<1; } if(~b & 1) return KGCD(a, b>>1); if(a > b) return KGCD((a-b)>>1, b);return KGCD((b-a)>>1, a);}
int LCM(int a,int b){ return a/KGCD(a,b)*b; }
inline ll qpow(ll n,ll m){n%=mod;ll ans=1;while(m){if(m%2) ans=(ans*n)%mod;m/=2;n=(n*n)%mod;}return ans;}
inline ll inv2(ll b){return qpow(b,mod-2);}
inline ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
int dir[5][2]={0,1,0,-1,1,0,-1,0};
long long a[100005];
long long b[100005];
long long tree[100005];
int n;
long long lowbit(long long x)
{
return x&(-x);
}
long long sum(long long x)
{
long long an
afdd
s=0;
while(x>0)
{
ans=(ans+tree[x])%mod;
x=x-lowbit(x);
}
return ans;
}
void add(long long x,long long valu)
{
while(x<=n)
{
tree[x]=(tree[x]+valu)%mod;
x=x+lowbit(x);
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(tree,0,sizeof(tree));
for(int i=0;i<n;i++)
{
scanf("%I64d",&a[i]);//FZ评测机用lld也是可以的 刚开始以为不行
b[i]=a[i];
}
sort(b,b+n);//讲数组排序后 进行离散化
for(int i=0;i<n;i++)
{
a[i]=lower_bound(b,b+n,a[i])-b+1;//查找下有多少个比他小的 但是树状数组最小从1开始所以加1
add(a[i],sum(a[i]-1)+1);
//然后开始讲a[i]这个点以后所有的点都加上他前边有多少比他小的和他本 身 }
long long ans=sum(n);//从上到下跑一边
printf("%I64d\n",ans);
}
return 0;
}
Problem H 第十四个目标
Accept: 44 Submit: 170
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
目暮警官、妃英里、阿笠博士等人接连遭到不明身份之人的暗算,柯南追踪伤害阿笠博士的凶手,根据几起案件现场留下的线索发现凶手按照扑克牌的顺序行凶。在经过一系列的推理后,柯南发现受害者的名字均包含扑克牌的数值,且扑克牌的大小是严格递增的,此外遇害者与毛利小五郎有关。为了避免下一个遇害者的出现,柯南将可能遭到暗算的人中的数字按关联程度排列了出来,即顺序不可改变。柯南需要知道共有多少种可能结果,满足受害人名字出现的数字严格递增,但是他柯南要找出关键的证据所在,所以这个任务就交给你了。
(如果你看不懂上面在说什么,这题是求一个数列中严格递增子序列的个数。比如数列(1,3,2)的严格递增子序列有(1)、(3)、(2)、(1,3)、(1,2),共5个。长得一样的但是位置不同的算不同的子序列,比如数列(3,3)的答案是2。)
Input
多组数据(<=10),处理到EOF。第一行输入正整数N(N≤100 000),表示共有N个人。
第二行共有N个整数Ai(1≤Ai≤10^9),表示第i个人名字中的数字。
Output
每组数据输出一个整数,表示所有可能的结果。由于结果可能较大,对1 000 000 007取模后输出。
Sample Input
31 3 2
Sample Output
5
Source
2016福州大学第十三届程序设计竞赛好题一枚,了解了离散化。
题意是求出每个i值对应的可以到达的严格递增子序列,然后从n往下来加一个和就好了。n就代表了前边所有的结果的和。
因为每一种都情况都用树状数组到了n。
所以离散化 然后树状数组
#include<stdio.h>
#include<iostream>
#include <algorithm>
#include<string.h>
#include<vector>
#include<math.h>
#include<queue>
#include<deque>
#include<map>
#include<set>
#define ll long long
#define INF 0x3f3f3f3f
const int mod = 1e9+7;
using namespace std;
int KGCD(int a,int b){if(a==0)return b;if(b==0)return a;if(~a&1){ if(b&1) return KGCD(a>>1,b);else return KGCD(a>>1,b>>1) <<1; } if(~b & 1) return KGCD(a, b>>1); if(a > b) return KGCD((a-b)>>1, b);return KGCD((b-a)>>1, a);}
int LCM(int a,int b){ return a/KGCD(a,b)*b; }
inline ll qpow(ll n,ll m){n%=mod;ll ans=1;while(m){if(m%2) ans=(ans*n)%mod;m/=2;n=(n*n)%mod;}return ans;}
inline ll inv2(ll b){return qpow(b,mod-2);}
inline ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
int dir[5][2]={0,1,0,-1,1,0,-1,0};
long long a[100005];
long long b[100005];
long long tree[100005];
int n;
long long lowbit(long long x)
{
return x&(-x);
}
long long sum(long long x)
{
long long an
afdd
s=0;
while(x>0)
{
ans=(ans+tree[x])%mod;
x=x-lowbit(x);
}
return ans;
}
void add(long long x,long long valu)
{
while(x<=n)
{
tree[x]=(tree[x]+valu)%mod;
x=x+lowbit(x);
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(tree,0,sizeof(tree));
for(int i=0;i<n;i++)
{
scanf("%I64d",&a[i]);//FZ评测机用lld也是可以的 刚开始以为不行
b[i]=a[i];
}
sort(b,b+n);//讲数组排序后 进行离散化
for(int i=0;i<n;i++)
{
a[i]=lower_bound(b,b+n,a[i])-b+1;//查找下有多少个比他小的 但是树状数组最小从1开始所以加1
add(a[i],sum(a[i]-1)+1);
//然后开始讲a[i]这个点以后所有的点都加上他前边有多少比他小的和他本 身 }
long long ans=sum(n);//从上到下跑一边
printf("%I64d\n",ans);
}
return 0;
}
相关文章推荐
- 第十四个目标 FZU - 2236 离散化 树状数组
- FZU 2236 第十四个目标(严格上升子序列个数 离散化 + 树状数组)
- FZU 2236 第十四个目标【Dp+离散化+树状数组】套路题
- fzu oj 2236 第十四个目标 树状数组好题 dp
- Foj 2236 第十四个目标 (树状数组+简单dp+离散化)
- fzu-oj 2236 第十四个目标-树状数组
- FZU2236 第十四个目标 dp+树状数组优化
- FZU 2236 第十四个目标 (线段树)
- 树状数组: fzu oj 2236 第十四个目标
- FZU2236 第十四个目标 (树状数组)
- DP+树状数组——FZU 2236 第十四个目标
- FZU 2236(离散化+树状数组)
- FZU 2236 第十四个目标 (dp+树状数组)
- FZu Problem 2236 第十四个目标 (线段树 + dp)
- fzoj 2236 第十四个目标 (树状数组&LIS&dp)好题
- fzuoj Problem 2236 第十四个目标(树状数组+dp)
- Problem 2236 第十四个目标
- Code Forces 652D Nested Segments(离散化+树状数组)
- hdu 4325 树状数组+离散化
- CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组