水题
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=100005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int main() {
freopen("tabs.in","r",stdin);
int cas;
scanf("%d",&cas);
while (cas--) {
int n,k,pos,ans;
scanf("%d%d",&n,&k);
if (k==1||k==n) ans=1; else ans=2;
if (k==1&&n==1) ans=0;
printf("%d\n",ans);
}
fclose(stdin);
return 0;
}
排序之后贪心。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=505,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int a[maxn];
int main() {
freopen("overcode.in","r",stdin);
int cas;
scanf("%d",&cas);
while (cas--) {
int n,i,j,ans=0;
scanf("%d",&n);
for (i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
int cnt=1;j=1;
for (i=2;i<=n;i++) {
if (abs(a[i]-a[j])>1000) {
ans+=cnt/6;
while (abs(a[i]-a[j])>1000) j++;
cnt=i-j+1;
} else {
cnt++;
if (cnt==6) ans++,cnt=0,j=i+1;
}
}
printf("%d\n",ans);
}
fclose(stdin);
return 0;
}
水题,模拟。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=55,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int c[maxn];
char s[maxn];
bool a[maxn];
int main() {
freopen("scoreboard.in","r",stdin);
int cas;
scanf("%d",&cas);
while (cas--) {
int n,i,ans;
for (i=0;i<13;i++) a[i]=true;
scanf("%d",&n);
scanf("%s",s);
for (i=0;i<n;i++) {
a[s[i]-'A']=false;
}
ans=-1;
for (i=0;i<13;i++) {
scanf("%d",&c[i]);
if (a[i])
if (ans==-1) ans=i; else
if (c[ans]<c[i]) ans=i;
}
printf("%c\n",(char)('A'+ans));
}
fclose(stdin);
return 0;
}
You want to prepare test cases for a problem with the following description:
"Given an array of n positive integers, and a number of queries. Each query will ask about a range [l, r](1 ≤ l ≤ r ≤ n), where each of the values between index l and index r (both inclusive) occurs an even number of times except one value. The answer to each query is the value that occurs an odd number of times in the given range."
You have generated an array of n positive integers, you need to know the number of valid queries you can ask on this array. A query is valid if it has an answer, and that answer is unique.
The first line of input contains a single integer T (1 ≤ T ≤ 64), the number of test cases.
The first line of each test case contains a single integer n (1 ≤ n ≤ 5000), the size of the array.
The next line contains n space-separated integers, a1, a2, ..., an (1 ≤ ai ≤ 106), the values of the array.
The total sum of n overall test cases doesn't exceed 72000.
For each test case, print a single line with the number of valid queries you can ask.
1 7 9 1 1 2 1 9 9
12
暴力大法好,O(n^2)水过
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=5005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int a[maxn],cnt[1000005];
int main() {
freopen("cases.in","r",stdin);
int cas;
scanf("%d",&cas);
mem0(cnt);
while (cas--) {
int n,i,j,ans=0,o,e;
scanf("%d",&n);
for (i=1;i<=n;i++) {
scanf("%d",&a[i]);
}
for (i=1;i<=n;i++) {
o=e=0;
for (j=i;j<=n;j++) {
cnt[a[j]]++;
if (cnt[a[j]]==1) e++; else
if (cnt[a[j]]%2) e++,o--; else e--,o++;
if (e==1) ans++;
}
for (j=i;j<=n;j++) cnt[a[j]]=0;
}
printf("%d\n",ans);
}
fclose(stdin);
return 0;
}
把每个数都拆成二进制记录每一位"1"的最晚出现时间,每次把合法区间的右界向右移一格,左界跟着一起移动(如果这时区间的或和超过所给上界),贪心的选择移动最少的方案。复杂度O(nlogn)。
贪心的依据是OR运算的单调不减性
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=100005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int a[maxn],last[25];
int main() {
freopen("wifi.in","r",stdin);
int cas;
scanf("%d",&cas);
while (cas--) {
int n,i,k;
scanf("%d%d",&n,&k);
int u=k,p=0,div;
while (u) {
u/=2;
p++;
}
div=p-1;
for (i=0;i<=25;i++) last[i]=0;
for (i=1;i<=n;i++) {
scanf("%d",&a[i]);
}
int now=0,j=1,ans=0;
for (i=1;i<=n;i++) {
if (a[i]>k) {
now=0;j=i+1;
continue;
}
now=now|a[i];
u=a[i],p=0;
while (u) {
if (u%2) last[p]=i;
u/=2;
p++;
}
if (now>k)
/* if (last[div]!=i) {
j=last[div]+1;
now=0;
for (int q=0;q<div;q++) {
if (last[q]>=j) now=now|(1<<q);
}
} else */{
int x=now,w=a[i],dig=inf;
for (int q=0;q<=div;q++) {
if (x%2==1&&w%2==0&&(now-(1<<q))<=k) {
dig=min(dig,last[q]+1);
}
x/=2;w/=2;
}
if (dig==inf) dig=i;
j=dig;
now=0;
for (int q=0;q<=div;q++) {
if (last[q]>=j) now=now|(1<<q);
}
}
ans=max(ans,i-j+1);
}
printf("%d\n",ans);
}
fclose(stdin);
return 0;
}
画图可以发现,对角线不行,对于n*n方阵相比(n-1)*(n-1)多出来的部分,横竖各每隔k个格子有一个不合法。由此可以推出公式。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int main() {
freopen("chess.in","r",stdin);
int cas;
scanf("%d",&cas);
while (cas--) {
ll n,k,ans;
scanf("%I64d%I64d",&n,&k);
if (n==k+1) ans=n*n-n; else {
ll m=(n-1)/(k+1);
ll a=m*2+1;
ans=n*n-(k+1)-(k+1)*(3+a)*m/2;
if (n%(k+1)!=0)
ans+=((k+1)-n%(k+1))*a;
}
printf("%I64d\n",ans);
}
fclose(stdin);
return 0;
}