水题 找两个数l, r 使得l, r之间所有数之和为n 找 -(n - 1) 到 n就好
代码
#include
using namespace std;
typedef long long ll;
ll n, l, r;
void solve()
{
cin >> n;
cout << 1 - n << ' ' << n << endl;
}
int main()
{
int t;
cin >> t;
while(t -- )
{
solve();
}
return 0;
}
我们可以把k转化为二进制 有点类似于快速幂的解法 水题
代码
#include
using namespace std;
typedef long long ll;
const ll P = 1e9 + 7;
ll read()
{
ll x = 0, k = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') k = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
return x * k;
}
ll n, k;
void solve()
{
n = read(), k = read();
ll ans = 0, t = 1;;
while (k)
{
if (k & 1) (ans += t) %= P;
(t *= n) %= P;
k >>= 1;
}
cout << ans << endl;
}
int main()
{
int t;
cin >> t;
while (t -- )
{
solve();
}
return 0;
}
水题 如果第n位相同 就取一个pos为n即可 如果n位不同 则从n/2到n取第一个相同的位数(n/2到n不存在n的因子 更不存在比n小的数的因子) 如果全都不同 则取n-1 和n即可
代码
#include
using namespace std;
const int N = 3e5 + 10;
int read()
{
int x = 0, k = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') k = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
return x * k;
}
int n;
char c;
char st[N];
void solve()
{
n = read();
cin >> c >> st + 1;
int pos = -1;
for (int i = 1; i <= n; i ++ )
if (st[i] != c) pos = i;
if (pos == -1) puts("0");
else if (pos != n) printf("1\n%d\n", n);
else
{
for (int i = n; i > n / 2; i -- )
if (st[i] == c)
{
pos = i;
break;
}
if (pos == n)
printf("2\n%d %d\n", n - 1, n);
else printf("1\n%d\n", pos);
}
}
int main()
{
int t;
cin >> t;
while (t -- )
{
solve();
}
return 0;
}
在很火的amongus游戏中会有m个人发表一次意见 说某人是否是卧底 问可能的最大的卧底数量为多少
我们可以这样考虑 假如a说b是好人 那么a和b肯定都是好人或者都是卧底 即身份相同 如果a说b是卧底 那么a和b身份肯定是相反的 所以我们可以想到用权值并查集来做这个题 用0和1来分别表示身份相同和身份不同 最后取每个集合中某个身份的最大值 相加即为答案
很经典的一种并查集题
代码
#include
#define rep(i, n) for (int i = 1; i <= (n); i ++ )
using namespace std;
const int N = 2e5 + 10;
inline int read()
{
register int x = 0, k = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') k = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
return x * k;
}
int n, m;
int p[N], dis[N], cou[N][2];
int find(int x)
{
if (x != p[x])
{
int root = find(p[x]);
dis[x] ^= dis[p[x]];
p[x] = root;
}
return p[x];
}
void solve()
{
n = read(), m = read();
rep(i, n) p[i] = i, dis[i] = 0, cou[i][0] = 1, cou[i][1] = 0;
bool flag = 1;
rep(i, m){
int a, b; char c[10];
a = read(), b = read(); scanf("%s", c);
bool val = c[0] == 'i';
int pa = find(a), pb = find(b);
if (pa == pb){
if ((dis[a] ^ dis[b]) != val) flag = false;
}
else{
p[pb] = pa;
dis[pb] = dis[a] ^ dis[b] ^ val;
cou[pa][1] += cou[pb][dis[pb] ^ 1];
cou[pa][0] += cou[pb][dis[pb]];
}
}
if (!flag) {puts("-1"); return;}
int res = 0;
rep(i, n) if (i == find(i)) res += max(cou[i][1], cou[i][0]);
printf("%d\n", res);
}
int main()
{
int t;
t = read();
while (t -- )
{
solve();
}
return 0;
}
给定一棵树 每个结点都可以染色 但是相邻结点有限制 即有两种颜色不能染
则每个结点有4中方式 根节点有6种 最后求相乘值即可
代码
#include
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
const ll P = 1e9 + 7;
int read()
{
int x = 0, k = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') k = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
return x * k;
}
ll k;
ll qmi(ll a, ll k)
{
ll res = 1;
while (k)
{
if (k % 2 == 1) res = res * a % P;
k >>= 1;
a = a * a % P;
}
return res;
}
void solve()
{
cin >> k;
ll k1 = (1ll << k) - 2;
ll ans = 6 * qmi(4ll, k1) % P;
cout << ans << endl;
}
int main()
{
solve();
return 0;
}