2017 JUST Programming Contest 4.0

来源:互联网 发布:笔记本硬盘坏了数据 编辑:程序博客网 时间:2024/06/08 07:14

A

题意:求所有区间的&和

思路:我们统计二进制中每一位的贡献,很显然如果连续一段区间二进制中某一位都为1,那么这个区间的任何子区间都满足答案,所以我们直接统计满足条件的子区间个数即可

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>#include <bitset>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define fi first#define se second#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int MOD = 1e9 + 7;const int qq = 1e6 + 10;const LL INF = 1e9 + 10;int num[qq];int n;int main(){int t;scanf("%d", &t);while(t--) {scanf("%d", &n);for(int i = 1; i <= n; ++i) {scanf("%d", num + i);}LL ans = 0, f = -1;LL l, r, cnt;for(int i = 0; i < 23; ++i) {cnt = 0;f = -1;for(int j = 1; j <= n; ++j) {if(f == -1) {if(num[j] & (1 << i)) {l = j;f = 1;}} else {if(!((num[j] & (1 << i)))) {f = -1;r = j - 1;cnt += (r - l + 1) + (1 + r - l) * (r - l) / 2;}}}if(f != -1) {r = n;cnt += (r - l + 1) + (1 + r - l) * (r - l) / 2;}ans += cnt * (LL)(1 << i);//printf("%lld\n", cnt);}printf("%lld\n", ans);}return 0;}


B

题意:ai = (a(i - 1) - i) % m,求整个数组a

思路:题意保证了至少一个不为-1,所以找个一个不为-1的,向前向后推一下即可

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>#include <bitset>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define fi first#define se second#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int MOD = 1e9 + 7;const int qq = 5e5 + 10;const LL INF = 1e9 + 10;int num[qq];int n, m;int main(){int t;scanf("%d", &t);while(t--) {scanf("%d%d", &n, &m);int id = -1;for(int i = 1; i <= n; ++i) {scanf("%d", num + i);if(num[i] != -1)id = i;}for(int i = id + 1; i <= n; ++i) {if(num[i] == -1)num[i] = (num[i - 1] + 1) % m;}for(int i = id - 1; i >= 1; --i) {if(num[i] == -1) {if(num[i + 1] == 0)num[i] = m - 1;elsenum[i] = num[i + 1] - 1;}}for(int i = 1; i <= n; ++i) {printf("%d%c", num[i], i == n ? '\n' : ' ');}}return 0;}


C

队友写的

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>#include <bitset>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define fi first#define se second#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int MOD = 1e9 + 7;const int qq = 2e5 + 10;const LL INF = 1e9 + 10;struct Node{int x,p;}a[qq],b[qq];int c[qq];bool cmp(const Node &u,const Node &v) {if(u.x==v.x) return u.p<v.p;return u.x<v.x;}int Bin(int key,int r) {int l=0,ans=0;while(l<=r) {int m=(l+r)>>1;if(b[m].x==key) {while(b[m+1].x==key) m++;return m;}else if(b[m].x<key) {ans=m;l=m+1;}else r=m-1;}return ans;}int main(){int t;scanf("%d",&t);while(t--) {int n;scanf("%d",&n);for(int i=0;i<n;i++) {scanf("%d",&a[i].x);b[i].x=a[i].x;a[i].p=i;b[i].p=i;}sort(b,b+n,cmp);for(int i=0;i<n;i++) {int num1=MOD-a[i].x-1;int p1;if(b[0].x>num1) p1=-1;else p1=Bin(num1,n-1);int p2=n-1;if(b[p1].p==i) p1--;if(b[p2].p==i) p2--;if(p1<0) c[i]=(b[p2].x+a[i].x)%MOD;else c[i]=max((b[p1].x+a[i].x)%MOD,(b[p2].x+a[i].x)%MOD);}for(int i=0;i<n;i++) printf("%d%c",c[i],i==n-1?'\n':' ');}return 0;}


D

题意:给出一个长度为n的字符串,然后q次询问,每次给你a b c,问你区间a b 内出现字符c的次数

思路:前缀维护一下讨论一下就行

 

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>#include <bitset>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define fi first#define se second#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int MOD = 1e9 + 7;const int qq = 5e5 + 10;const LL INF = 1e9 + 10;int num[qq][26], tot[26];int n, m;char st[qq];int main(){int t;scanf("%d", &t);while(t--) {scanf("%d%d", &n, &m);scanf("%s", st);int len = strlen(st);mst(num[0], 0);mst(tot, 0);for(int i = 0; i < n; ++i) {if(i != 0) {for(int j = 0; j < 26; ++j) {num[i][j] = num[i - 1][j];}}num[i][st[i] - 'a']++;tot[st[i] - 'a']++;}char s[5];while(m--) {int a, b;scanf("%d%d", &a, &b);scanf("%s", s);a--, b--;LL ans = 0;if(b - a + 1 < n) {a %= n, b %= n;if(a <= b) {if(a - 1 < 0) {ans += num[b][s[0] - 'a'];} else {ans += num[b][s[0] - 'a'] - num[a - 1][s[0] - 'a'];}} else {if(a - 1 < 0) {ans += num[n - 1][s[0] - 'a'] + num[b][s[0] - 'a'];} else {ans += num[n - 1][s[0] - 'a'] - num[a - 1][s[0] - 'a'] + num[b][s[0] - 'a'];}}} else {LL tmp = (b - a + 1) / n;if((b - a + 1) % n == 0) {ans = tmp * tot[s[0] - 'a'];} else {ans = tmp * tot[s[0] - 'a'];a %= n, b %= n;//printf("QQQ %lld\n", ans);if(a <= b) {if(a - 1 < 0) {ans += num[b][s[0] - 'a'];} else {ans += num[b][s[0] - 'a'] - num[a - 1][s[0] - 'a'];}} else {if(a - 1 < 0) {ans += num[n - 1][s[0] - 'a'] + num[b][s[0] - 'a'];} else {ans += num[n - 1][s[0] - 'a'] - num[a - 1][s[0] - 'a'] + num[b][s[0] - 'a'];}}//ans = (LL)tmp * tot[s[0] - 'a'] + (LL)(num[n - 1][s[0] - 'a'] - num[a - 1][s[0] - 'a']) + (num[b][s[0] - 'a']);}}printf("%lld\n", ans);}}

G

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>#include <bitset>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define fi first#define se second#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int MOD = 1e9 + 7;const int qq = 1e6 + 10;const LL INF = 1e9 + 10;int num[qq];int pre[qq], suf[qq];int main(){int t;scanf("%d", &t);while(t--) {int n;scanf("%d", &n);for(int i = 1; i <= n; ++i) {scanf("%d", num + i);}for(int i = 1; i <= n; ++i) {if(i == 1)pre[i] = num[i];elsepre[i] = max(pre[i - 1], num[i]);}for(int i = n; i >= 1; --i) {if(i == n)suf[i] = num[i];elsesuf[i] = min(suf[i + 1], num[i]);}int cnt = 0;for(int i = 2; i < n; ++i) {if(pre[i - 1] <= num[i] && num[i] <= suf[i + 1]) {cnt++;}}printf("%d\n", cnt);}return 0;}


H

题意:给出n*m的矩阵,问你能否将行数为1 n 列数为1 m的全部是1,每次可以交换两个位置的元素,求出最小交换次数,不可就输出-1

思路:很简单,判断一下1的个数即可

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>#include <bitset>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define fi first#define se second#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int MOD = 1e9 + 7;const int qq = 5e5 + 10;const int INF = 1e9 + 10;char st[105];int main(){int t;scanf("%d", &t);while(t--) {int n, m;scanf("%d%d", &n, &m);int cnt1, cnt2, cnt3, cnt4;cnt1 = cnt2 = cnt3 = cnt4 = 0;for(int i = 1; i <= n; ++i) {scanf("%s", st + 1);for(int x, j = 1; j <= m; ++j) {x = st[j] - '0';if(i == 1 || j == 1 || i == n || j == m) {if(x == 0)cnt1++;} else {if(x == 1)cnt2++;}}}if(cnt2 >= cnt1) {printf("%d\n", cnt1);} else {puts("-1");}}return 0;}



I

很简单的dp

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>#include <bitset>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define fi first#define se second#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int MOD = 1e9 + 7;const int qq = 5e5 + 10;const LL INF = 1e9 + 10;int num[qq], pos[qq];int dp[qq];int main(){int t;scanf("%d", &t);while(t--) {int n;scanf("%d", &n);for(int i = 1; i <= n; ++i) {scanf("%d", num + i);}mst(pos, -1);dp[1] = 0, pos[num[1]] = 1;for(int i = 2; i <= n; ++i) {dp[i] = dp[i - 1] + 1;if(pos[num[i]] != -1) {dp[i] = min(dp[i], dp[pos[num[i]]] + 1);}pos[num[i]] = i;}printf("%d\n", dp[n]);}return 0;}


J

队友写的

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>#include <bitset>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define fi first#define se second#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int MOD = 1e9 + 7;const int qq = 1e5 + 10;const LL INF = 1e9 + 10;LL a[qq];int main(){int t;scanf("%d", &t);while(t--) {int n;scanf("%d",&n);for(int i=0;i<n;i++) scanf("%lld",&a[i]);if(n==1) {printf("%lld\n",a[0]%MOD);continue;}LL sum=(a[0]+a[1]+a[0]*a[1]%MOD)%MOD;for(int i=2;i<n;i++) {sum=(sum*(a[i]+1)%MOD+a[i])%MOD;}printf("%lld\n",sum%MOD);}return 0;}



K

队友写的

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>#include <bitset>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define fi first#define se second#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int MOD = 1e9 + 7;const int qq = 1e5 + 10;const LL INF = 1e9 + 10;LL a[30],F[15];char s[25];void init() {F[0]=1LL;for(int i=1;i<12;i++) F[i]=F[i-1]*1LL*i;}int main(){init();int t;scanf("%d", &t);while(t--) {mst(a,0);int n;scanf("%d%s",&n,s);for(int i=0;i<n;i++) a[s[i]-'a']++;int cnt=0;for(int i=0;i<26;i++) {if(a[i]&1) cnt++;a[i]/=2LL;}if((n&1)&&cnt!=1||!(n&1)&&cnt!=0) {printf("0\n");continue;}LL sum=F[(n>>1)];for(int i=0;i<26;i++) sum/=F[a[i]];printf("%lld\n",sum);}return 0;}