The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple (Mirror)
B题
思路
因为
\[
x=\sum\limits_{k=1}^{n}ka_k\\
y=\sum\limits_{k=1}^{n}ka_{k}^{2}
\]
我们设交换前和交换后的这两个等式的值设为\(x_1,y_1,x_2,y_2\),现在我们开始愉快的推公式
\[
\begin{aligned}
&x_1-x_2=(i-j)(a_i-a_j)&\\
&y_1-y_2=(i-j)(a_i^2-a_j^2)&\\
\Rightarrow &\frac{y1-y2}{x_1-x_2}=a_i-a_j&(1)\\
&j=i-\frac{x_1-x_2}{a_i-a_j}&(2)
\end{aligned}
\]
然后我们枚举每一个\(i\),根据\((1)(2)\)计算出\(a_j\)和\(j\)然后判断现在在\(j\)这个位置上的值是不是你算出来的这个\(a_j\),是就答案加一否则答案不变。
#include <bits/stdc++.h>
using namespace std;
#define bug printf("********\n")
#define FIN freopen("in.txt","r",stdin)
#define debug(x) cout<<"["<<x<<"]"<<endl
typedef long long LL;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n;
LL x, y, b[maxn], cnt[maxn];
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
scanf("%d", &t);
while(t--) {
scanf("%d%lld%lld", &n, &x, &y);
LL xx = 0, yy = 0;
for(int i = 1; i <= n; ++i) {
scanf("%lld", &b[i]);
cnt[b[i]]++;
xx += b[i] * i;
yy += b[i] * b[i] * i;
}
LL dx = xx - x, dy = yy - y;
LL ans = 0;
if(dx == 0 && dy == 0) {
for(int i = 1; i <= n; ++i) {
ans += cnt[b[i]] - 1;
cnt[b[i]]--;
}
printf("%lld\n", ans);
for(int i = 1; i <= n; ++i) cnt[b[i]] = 0;
continue;
}
if(dx == 0 || dy == 0 || dy % dx) {
printf("0\n");
for(int i = 1; i <= n; ++i) cnt[b[i]] = 0;
continue;
}
LL num = dy / dx;
for(int i = 1; i <= n; ++i) {
if(num - b[i] <= 0) continue;
LL num1 = b[i], num2 = num - num1;
if(num1 == num2 || dx % (num1 - num2) != 0) continue;
LL pos = i - dx / (num1 - num2);
if(pos >= 1 && pos < i && b[pos] == num2) ans++;
}
printf("%lld\n", ans);
for(int i = 1; i <= n; ++i) cnt[b[i]] = 0;
}
return 0;
}
E题
思路
线段树,对于每个点它是否修改取决于在原序列是否有比它大的数或者比它大的数进行过操作。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n;
int a[maxn], num[maxn];
vector<int> v;
struct node {
int l, r, sum;
}segtree[maxn<<2];
int getid(int x) {
return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
}
void push_up(int rt) {
segtree[rt].sum = segtree[lson].sum + segtree[rson].sum;
}
void build(int rt, int l, int r) {
segtree[rt].l = l, segtree[rt].r = r;
segtree[rt].sum = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
}
void update(int rt, int pos) {
if(segtree[rt].l == segtree[rt].r) {
segtree[rt].sum++;
return;
}
int mid = (segtree[rt].l + segtree[rt].r) >> 1;
if(pos <= mid) update(lson, pos);
else update(rson, pos);
push_up(rt);
}
int query(int rt, int l, int r) {
if(segtree[rt].l == l && segtree[rt].r == r) {
return segtree[rt].sum;
}
int mid = (segtree[rt].l + segtree[rt].r) >> 1;
if(r <= mid) return query(lson, l, r);
else if(l > mid) return query(rson, l, r);
else return query(lson, l, mid) + query(rson, mid + 1, r);
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
v.clear();
priority_queue<pii> q;
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
num[i] = 0;
v.push_back(a[i]);
q.push({a[i], i});
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
build(1, 1, v.size() + 1);
for(int i = 1; i <= n; ++i) {
num[i] = query(1, getid(a[i]) + 1, v.size() + 1);
update(1, getid(a[i]));
}
int x;
int ans = 0, las = 0;
build(1, 1, v.size() + 1);
while(!q.empty()) {
int x = q.top().second; q.pop();
if(num[x] || query(1, getid(a[x]) + 1, v.size() + 1)) {
ans++;
update(1, getid(a[x]));
}
}
printf("%d\n", ans);
}
return 0;
}
F题
思路
暴力模拟即可。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t;
vector<char> v;
char s[105];
set<char> st;
int main() {
scanf("%d", &t);
st.insert({'a', 'e', 'i', 'y', 'o', 'u'});
while(t--) {
scanf("%s", s);
v.clear();
int len = strlen(s), flag = 0;
for(int i = 0; i < len; ++i) {
if(!st.count(s[i])) v.push_back(s[i]), flag = 1;
else if(!flag) v.push_back(s[i]), flag = 1;
}
for(int i = 0; i < (int)v.size(); ++i) {
printf("%c", v[i]);
}
printf("\n");
}
return 0;
}
G题
思路
暴力判断。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n;
bool check(int x) {
return x % 7 == 0 && x % 4 != 0;
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
while(!check(n)) n++;
printf("%d\n", n);
}
return 0;
}
H题
思路实现如下
暴力枚举每个点删除会对答案的影响,然后对所有情况取最小值。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n;
int a[maxn];
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
for(int i = 0; i <= n + 1; ++i) {
a[i] = inf;
}
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
int sum = 0;
for(int i = 2; i < n; ++i) {
if(a[i] > a[i-1] && a[i] > a[i+1]) {
sum++;
}
}
int ans = sum;
for(int i = 1; i <= n; ++i) {
int num = 0;
if(a[i] > a[i-1] && a[i] > a[i+1]) {
num++;
if(i >= 2 && a[i-1] > a[i-2] && a[i-1] > a[i+1]) num--;
if(i <= n - 2 && a[i+1] > a[i+2] && a[i+1] > a[i-1]) num--;
} else {
if(i >= 2) {
if(a[i-1] > a[i-2] && a[i-1] > a[i]) num++;
if(a[i-1] > a[i-2] && a[i-1] > a[i+1]) num--;
}
if(i <= n - 2) {
if(a[i+1] > a[i] && a[i+1] > a[i+2]) num++;
if(a[i+1] > a[i+2] && a[i+1] > a[i-1]) num--;
}
}
ans = min(ans, sum - num);
}
printf("%d\n", ans);
}
return 0;
}
I题
思路
从\(4\)的倍数往上每四个数异或后都会是\(0\),因此对\(a\)和\(b\)枚举到在\([a,b]\)间离它们最近的\(4\)的倍数,然后把这中间的数进行异或即可。
代码实现如下
import java.util.*;
import java.math.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t-- != 0) {
BigInteger a = sc.nextBigInteger();
BigInteger b = sc.nextBigInteger();
int ans = 0;
while(!a.mod(BigInteger.valueOf(3)).equals(BigInteger.ZERO) && a.compareTo(b) <= 0) {
ans++;
a = a.add(BigInteger.ONE);
}
while(!b.mod(BigInteger.valueOf(3)).equals(BigInteger.ZERO) && b.compareTo(a) > 0) {
ans++;
b = b.subtract(BigInteger.ONE);
}
System.out.println(ans % 2);
}
sc.close();
}
}
T = eval(input())
while(T):
T -= 1
a, b = map(int, input().split())
ans = 0
while(a % 3 != 0 and a <= b):
ans += 1
a += 1
while(b % 3 != 0 and b > a):
ans += 1
b -= 1
print(ans % 2)
J题
思路
我们先用并查集来维护联通块,为了保持字典序最小,我们从小到大将每个联通块取一个数放进优先队列,然后跑\(bfs\)即可。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n, m, x, y;
vector<int> G[maxn];
priority_queue<int> q;
int fa[maxn], vis[maxn], pp[maxn];
int fi(int x) {
return fa[x] == x ? x : fa[x] = fi(fa[x]);
}
void mer(int x, int y) {
int p1 = fi(x), p2 = fi(y);
if(p1 == p2) return;
if(p1 < p2) {
fa[p2] = p1;
} else {
fa[p1] = p2;
}
}
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
fa[i] = i;
pp[i] = vis[i] = 0;
G[i].clear();
}
for(int i = 1; i <= m; ++i) {
scanf("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
mer(x, y);
}
while(!q.empty()) q.pop();
for(int i = 1; i <= n; ++i) {
int p = fi(i);
if(pp[p]) continue;
q.push(-p);
pp[p] = 1;
}
printf("%d\n", (int)q.size());
int flag = 0;
while(!q.empty()) {
int u = -q.top(); q.pop();
if(vis[u]) continue;
if(flag) printf(" ");
flag = 1;
printf("%d", u);
vis[u] = 1;
for(int i = 0; i < (int)G[u].size(); ++i) {
int v = G[u][i];
if(vis[v]) continue;
q.push(-v);
}
}
printf("\n");
}
return 0;
}
K题
思路
这题我们分两种情况进行分析:
\(1.s==t:\)这种情况我们可以用\(manacher\)将\(s\)中的所有回文子串数计算出来;
\(2.s!=t:\)这种情况我们先找到\(s\)中与\(t\)不相同的最左最右的端点,然后判断这一段能否翻转使得\(s==t\),不能答案就是\(0\),否则就枚举这个区间能够向外延伸多远。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n;
LL x, y, xx, yy, b[maxn];
map<LL, int> cnt;
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif
scanf("%d", &t);
while(t--) {
scanf("%d%lld%lld", &n, &x, &y);
xx = yy = 0;
cnt.clear();
for(int i = 1; i <= n; ++i) {
scanf("%lld", &b[i]);
xx += b[i] * i;
yy += b[i] * b[i] * i;
cnt[b[i]]++;
}
LL ans = 0;
if(x != xx) {
if((y - yy) % (x - xx) != 0) {
printf("0\n");
continue;
}
LL num = (y - yy) / (x - xx);
for(int i = 1; i <= n; ++i) {
LL num1 = b[i], num2 = num - b[i];
if(num1 == num2) continue;
LL tmp = num1 - num2;
if((x - xx) % tmp != 0) continue;
LL j = (x - xx) / tmp;
LL pos = i + j;
if(pos >= 1 && pos <= n && b[pos] == num2) ans++;
}
printf("%lld\n", ans/2);
} else {
if(y == yy) {
for(int i = 1; i <= n; ++i) {
ans += cnt[b[i]] - 1;
cnt[b[i]]--;
}
}
printf("%lld\n", ans);
}
}
return 0;
}
The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple (Mirror)的更多相关文章
- The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - L Doki Doki Literature Club
Doki Doki Literature Club Time Limit: 1 Second Memory Limit: 65536 KB Doki Doki Literature Club ...
- 2018浙江省赛(ACM) The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple
我是铁牌选手 这次比赛非常得爆炸,可以说体验极差,是这辈子自己最脑残的事情之一. 天时,地利,人和一样没有,而且自己早早地就想好了甩锅的套路. 按理说不开K就不会这么惨了啊,而且自己也是毒,不知道段错 ...
- The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored E.Sequence in the Pocket(思维题)
传送门 题意: 给出一个序列,你可以将任意一个数移到最前面: 求最少需要移动多少次,可以是此序列变成非递减序列: 思路: 定义 (ai,aj) 为逆序对 ( i < j , ai > aj ...
- The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored(E F G H I)
http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=392 E:Sequence in the Pocket 思路:从 ...
- The 14th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - F 贪心+二分
Heap Partition Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge A sequence S = { ...
- The 14th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - C 暴力 STL
What Kind of Friends Are You? Time Limit: 1 Second Memory Limit: 65536 KB Japari Park is a larg ...
- The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - M Lucky 7
Lucky 7 Time Limit: 1 Second Memory Limit: 65536 KB BaoBao has just found a positive integer se ...
- The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - J CONTINUE...?
CONTINUE...? Time Limit: 1 Second Memory Limit: 65536 KB Special Judge DreamGrid has clas ...
- The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - B King of Karaoke
King of Karaoke Time Limit: 1 Second Memory Limit: 65536 KB It's Karaoke time! DreamGrid is per ...
随机推荐
- 分割nginx日志
#!/bin/bash #此脚本用于自动分割Nginx的日志,包括access.log和error.log #每天00:00执行此脚本 将前一天的access.log重命名为access-xxxx-x ...
- SecureCRT-登录unix/linux服务器主机的软件
百度百科说辞: SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录UNIX或Linux服务器主机的软件. SecureCRT支持SSH,同时支持Te ...
- 将博客转成pdf
前些天无意间看到了“birdben”的博客,写的比较详细,但是最新的文章更新时间是“2017-05-07”,时间很是久远,本打算有时间认真学习一下博主所写的文章,但是担心网站会因为某些原因停止服务,于 ...
- jquery监听回车
jquery监听回车 <pre> $("#loginusername, #loginpassword, #code").keydown(function() { if( ...
- 使用Mysql中的concat函数或正则匹配来快速批量生成用于执行的sql语句
背景介绍 今天需要给一张表里面补数据,需要按照行的维度进行update,如果是个别数据那么直接写update语句就可以了,但是场景要求的是将整表的数据进行update,要实现这个需求就不能只靠蛮力了, ...
- git clean用法
git clean用法 想批量删除branch中新加的文件(untracked files),,git reset --hard不行- 首先确认要删除的文件 git clean -fd -n ...
- 一致性hash算法应用场景、详解与实现(JAVA)
一.概述 在分布式环境下,开发者通常会遇到一些分布存储的场景,例如数据库的分库分表(比如用户id尾号为1的放入数据库1,id尾号为2的放入数据库2):又如分布式缓存数据的获取(比如根据ip地址进行缓存 ...
- 【笔试题】Overriding in Java
笔试题 Overriding in Java Question 1 以下程序的输出结果为( ). class Derived { protected final void getDetails() { ...
- 全栈项目|小书架|微信小程序-书籍详情功能实现
效果图 实现分析 从效果图上分析,书籍详情是通过点击首页的item后进入. 进入详情页之后页面顶部显示书籍的相关信息,同时判断用户是否登录,未登录则弹出一个授权登录窗口. 点击登录之后即可加载出用户评 ...
- 【代码优化】C#遍历所有控件(Control方法)
直接上代码: /// <summary> /// 判断价格是否可以购买技能的方法 /// </summary> /// <param name="btnBuyA ...