Problem 1. Difference
数列 A1, A2, . . . , AN ,Q 个询问 (Li , Ri),ALi, ALi+1, . . . , ARi是否互不相同。
Input
第 1 行,2 个整数 N, Q,
第 2 行,N 个整数 A1, A2, . . . , AN
Q 行,每行 2 个整数 Li , Ri
Output
对每个询问输出一行,“Yes” 或者 “No”
• 对于 50% 的数据,N, Q ≤ 10^3
• 对于 100% 的数据,1 ≤ N, Q ≤ 10^5, 1 ≤ Ai ≤ N, 1 ≤ Li ≤ Ri ≤ N
题解:既然本题要求查询从l 到 r 的区间内是否有重复元素,我们不妨对于每一个元素记录一下下一个与它相同的点的位置,然后我们只需要查询L到R中每个元素的重复位置的最小值(离L最近),记为min,当min比R大的时候,显然就是一个不重复的序列了。实现的话ST和线段树都可以。
Problem 2. Increasing
数列 A1, A2, . . . , AN ,修改最少的数字,使得数列严格单调递增。
Input
第 1 行,1 个整数 N
第 2 行,N 个整数 A1, A2, . . . , AN
Output
1 个整数,表示最少修改的数字
• 对于 50% 的数据,N ≤ 10^3
• 对于 100% 的数据,1 ≤ N ≤ 10^5, 1 ≤ Ai ≤ 10^9
题解:实际上这个题题目描述漏了一个条件,那就是:插入的数可以为非整数,至少数据是这样的2333,这也导致我当时这个题全WA
然后,这个题显然就是个最长上升子序列啦~(ans=n-Length)length是最长的上升子序列;
当然,这个题是要加优化的100000的数据不是闹着玩的~~
1 #include <cstdio> 2 using namespace std; 3 int a[100010]; 4 int f[100010]; 5 int main() 6 { 7 freopen("incr.in", "r", stdin); 8 freopen("incr.out", "w", stdout); 9 int n; 10 scanf("%d", &n); 11 for(int i = 1; i <= n; i++) 12 scanf("%d", &a[i]); 13 int l = 0; 14 for(int i = 1; i <= n; i++) 15 { 16 if(a[i] > f[l]) 17 f[++l] = a[i]; 18 else 19 { 20 int u = 1, y = l; 21 while(u != y) 22 { 23 int mid = (y + u) / 2; 24 if(f[mid] > a[i])y = mid; 25 else u = mid + 1; 26 } 27 f[u] = a[i]; 28 } 29 } 30 printf("%d", n - l); 31 return 0; 32 }