sichuan2017 E. Longest Increasing Subsequence(LIS变形)
2017-07-19 13:15
363 查看
E. Longest Increasing Subsequence
Bobo learned how to compute Longest Increasing Subsequence (LIS) in O(n log n) in ICPCCamp.
For those who did not attend ICPCCamp as Bobo, recall LIS(a1, a2, … , an) is defined as f[1]2 ⊕ f[2]2 ⊕
· · · ⊕ f
2 where ⊕ denotes the exclusive-or (XOR) and f is calculated as follows.
for i in [1, 2, …, n]
f[i] = 1
for j in [1, 2, …, i - 1]
if a[j] < a[i] then
f[i] = max(f[i], f[j] + 1)
Given sequence A = (a1, a2, … , an), Bobo would like to find LIS(B1), LIS(B2), … , LIS(Bn) where Bi
is the
sequence after removing the i-th element from A.
Input
The input contains zero or more test cases and is terminated by end-of-file. For each test case:
The first line contains an integer n. The second line contains n integers a1, a2, … , an.
• 2 ≤ n ≤ 5000
• 1 ≤ ai ≤ n
• The number of test cases does not exceed 10.
Output
For each case, output n integers which denote LIS(B1), LIS(B2), … , LIS(Bn).
Sample Input
5
2 5 3 1 4
Sample Output
5 13 0 8 0
题意:给你一个长度为n的序列,问当删除第i个数后,剩余数的LIS的平方的异或和是多少。
题解:首先o(nlogn)预处理出以ai为结尾的LIS的长度。
然后对于每次删除的数ai来说,位于ai前面的LIS的长度不变,后面的要么不变,要么-1。现在判断长度是否-1,假设ai后面存在一个数aj,如果aj前面存在一个数ak(!=ai),使得ak的LIS==aj的LIS-1并且ak < aj.则删除ai后,对aj的LIS没有影响。如果想对于任意的aj都尽量满足没有影响,则ak的值尽可能小。所以用s[]维护长度为i 的最小结尾。
代码:
Bobo learned how to compute Longest Increasing Subsequence (LIS) in O(n log n) in ICPCCamp.
For those who did not attend ICPCCamp as Bobo, recall LIS(a1, a2, … , an) is defined as f[1]2 ⊕ f[2]2 ⊕
· · · ⊕ f
2 where ⊕ denotes the exclusive-or (XOR) and f is calculated as follows.
for i in [1, 2, …, n]
f[i] = 1
for j in [1, 2, …, i - 1]
if a[j] < a[i] then
f[i] = max(f[i], f[j] + 1)
Given sequence A = (a1, a2, … , an), Bobo would like to find LIS(B1), LIS(B2), … , LIS(Bn) where Bi
is the
sequence after removing the i-th element from A.
Input
The input contains zero or more test cases and is terminated by end-of-file. For each test case:
The first line contains an integer n. The second line contains n integers a1, a2, … , an.
• 2 ≤ n ≤ 5000
• 1 ≤ ai ≤ n
• The number of test cases does not exceed 10.
Output
For each case, output n integers which denote LIS(B1), LIS(B2), … , LIS(Bn).
Sample Input
5
2 5 3 1 4
Sample Output
5 13 0 8 0
题意:给你一个长度为n的序列,问当删除第i个数后,剩余数的LIS的平方的异或和是多少。
题解:首先o(nlogn)预处理出以ai为结尾的LIS的长度。
然后对于每次删除的数ai来说,位于ai前面的LIS的长度不变,后面的要么不变,要么-1。现在判断长度是否-1,假设ai后面存在一个数aj,如果aj前面存在一个数ak(!=ai),使得ak的LIS==aj的LIS-1并且ak < aj.则删除ai后,对aj的LIS没有影响。如果想对于任意的aj都尽量满足没有影响,则ak的值尽可能小。所以用s[]维护长度为i 的最小结尾。
代码:
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<vector> #include<queue> #include<algorithm> #include<map> using namespace std; typedef long long int ll; typedef pair<int,int>pa; const int N=1e5+10; const int MOD=1e9+7; const ll INF=1e18; const int inf=1e4; int read() { int x=0; char ch = getchar(); while('0'>ch||ch>'9')ch=getchar(); while('0'<=ch&&ch<='9') { x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); } return x; } /************************************************************/ int n; int a ; int dp ;//记录以ai结尾的LIS的长度 int s ;//记录长度为i的LIS的最小结尾 int f ;//记录长度为i的LIS的结尾 void init() { for(int i=1;i<=n;i++) scanf("%d",&a[i]); fill(dp,dp+N-1,inf); int cnt=0; f[++cnt]=a[1]; dp[1]=cnt; for(int i=2;i<=n;i++) { if(a[i]>f[cnt]) { f[++cnt]=a[i]; dp[i]=cnt; } else { int pos=lower_bound(f+1,f+cnt,a[i])-f; f[pos]=a[i]; dp[i]=pos; } } } int main() { while(~scanf("%d",&n)) { init(); for(int i=1;i<=n;i++) { memset(s,0x3f3f3f3f,sizeof(s)); s[0]=0; ll ans=0; for(int j=1;j<i;j++) { s[dp[j]]=min(s[dp[j]],a[j]); ans^=(ll)dp[j]*(ll)dp[j]; } for(int j=i+1;j<=n;j++) { if(a[j]>s[dp[j]-1]) { s[dp[j]]=min(s[dp[j]],a[j]); ans^=(ll)dp[j]*(ll)dp[j]; } else { s[dp[j]-1]=min(s[dp[j]-1],a[j]); ans^=(ll)(dp[j]-1)*(ll)(dp[j]-1); } } if(i!=1) printf(" "); printf("%lld",ans); } printf("\n"); } }
相关文章推荐
- Longest Increasing Subsequence (LIS) 的java实现
- 最长上升子序列 LIS(Longest Increasing Subsequence)
- 【LIS】 洛谷 HAOI2007 上升序列(Longest Increasing Subsequence)
- 最长上升子序列 LIS (Longest Increasing Subsequence)
- Longest Increasing Subsequence,LIS初步
- Dynamic Programming之Longest Increasing Subsequence (LIS)问题
- 最长上升子序列 LIS(Longest Increasing Subsequence)
- Dynamic Programming之Longest Increasing Subsequence (LIS)问题
- Longest Increasing Subsequence(LIS)
- 最长上升子序列 LIS(Longest Increasing Subsequence)
- LIS(Longest Increasing Subsequence)最长上升(不下降)子序列
- DP中的LIS:longest increasing subsequence
- 求出最长非降子序列的长度--LIS:longest increasing subsequence
- Longest Increasing Subsequence[LIS 最长上升子序列问题] (Longest Ordered Subsequence) POJ - 2533 队列优化
- 最长上升子序列 LIS (Longest Increasing Subsequence)
- 最长上升子序列(Longest Increasing Subsequence,LIS)
- 最长上升子序列 LIS(Longest Increasing Subsequence)---DP
- DP(dynamic programming)之LIS(longest increasing subsequence)问题(转)
- 最长上升子序列LIS(Longest Increasing Subsequence)
- @陈利人 : #面试题#LIS问题:这个LIS问题,可不是Longest Increasing Subsequence,而是Largest Independent Set。