问能否构造一个匹配串能和a、b匹配却不能和c匹配。
如果a和b某一位置上字母相同且和c这一位置上字母不同的话一定能构造出来
还有如果a、b、c某一位置上字母都不同的话匹配串放c这一位置上的大写字母也一定能构造出来
#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
typedef long long ll;
void solve()
{
int n;
cin >> n;
string a, b, c;
cin >> a >> b >> c;
int f = 0;
for(int i = 0; i < n; i ++)
{
if(a[i] == b[i] && a[i] != c[i])
{
f = 1;
break;
}
if(a[i] != b[i] && a[i] != c[i] && b[i] != c[i])
{
f = 1;
break;
}
}
if(f)cout << "YES" << endl;
else cout << "NO" << endl;
}
int main()
{
IOS
int _;
cin >> _;
while(_ --)
{
solve();
}
return 0;
}
组成三角形只有两种情况:
1.三条边等长
2.两条边等长,第三条边比另外两条边短
没有其他情况了
#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
typedef long long ll;
const int N = 300010;
int a[N];
ll C(ll A, ll B)
{
if(A < B)return 0;
if(B == 2)
{
ll res = A * (A - 1) / 2;
return res;
}
ll res = A * (A - 1) * (A - 2) / 6;
return res;
}
void solve()
{
int n;
cin >> n;
for(int i = 0; i <= n; i ++)a[i] = 0;
for(int i = 0; i < n; i ++)
{
int x;
cin >> x;
a[x] ++;
}
ll ans = 0, cnt = 0;
for(int i = 0; i <= n; i ++)
{
ans += C(a[i], 3) + cnt * C(a[i], 2);
cnt += a[i];
}
cout << ans << endl;
}
int main()
{
IOS
int _;
cin >> _;
while(_ --)
{
solve();
}
return 0;
}
前缀和,只要计算每两个城市之前的往返费用即可
#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
typedef long long ll;
const int N = 100010;
int x[N];
int a[N], b[N];
void solve()
{
int n;
cin >> n;
for(int i = 0; i <= n; i ++)a[i] = b[i] = 0;
for(int i = 1; i <= n; i ++)cin >> x[i];
a[1] = 1, b[n] = 1;
for(int i = 2; i < n; i ++)//1 - n-1
{
if(x[i + 1] - x[i] < x[i] - x[i - 1])a[i] = 1;
else a[i] = x[i + 1] - x[i];
}
for(int i = n - 1; i > 1; i --)//2 - n
{
if(x[i] - x[i - 1] < x[i + 1] - x[i])b[i] = 1;
else b[i] = x[i] - x[i - 1];
}
for(int i = 1; i <= n; i ++)
{
a[i] += a[i - 1];
b[i] += b[i - 1];
}
int Q;
cin >> Q;
while(Q --)
{
int l, r;
cin >> l >> r;
if(l < r)//[l, r-1]
{
cout << a[r - 1] - a[l - 1] << endl;
}
else//[r+1, l]
{
cout << b[l] - b[r] << endl;
}
}
}
int main()
{
IOS
int _;
cin >> _;
while(_ --)
{
solve();
}
return 0;
}
不难想到最多会删n次,和建立链表
但难点在如何快速地实现删这n次,暴力做法在n方,明显不可取
但有一个性质是下一轮新删的点必然是由这一轮删的点影响的,根据这个性质和set的排序,可以把时间复杂度降到nlogn,可取
可以把每个点和它本轮收到的实际伤害存到set中,每一次取<0的点,然后再把这些点影响到的点更新一下即可
#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair PII;
const int N = 300010;
int n;
int a[N], d[N];
int l[N], r[N];
bool st[N];
set S;
int get(int x)
{
return d[x] - a[l[x]] - a[r[x]];
}
void del(int x)
{
if(l[x] && !st[l[x]])S.erase({get(l[x]), l[x]});//把左右更新一下,原来的存在的话就把原来的删了
if(r[x] && !st[r[x]])S.erase({get(r[x]), r[x]});
l[r[x]] = l[x];
r[l[x]] = r[x];
if(l[x] && !st[l[x]])S.insert({get(l[x]), l[x]});
if(r[x] && !st[r[x]])S.insert({get(r[x]), r[x]});
}
void solve()
{
S.clear();
cin >> n;
for(int i = 1; i <= n; i ++)cin >> a[i];
for(int i = 1; i <= n; i ++)cin >> d[i];
for(int i = 1; i <= n; i ++)
{
l[i] = i - 1, r[i] = i + 1;
st[i] = false;
}
r[n] = 0;
//a[n + 1] = 0;
for(int i = 1; i <= n; i ++)
{
S.insert({get(i), i});
}
for(int i = 1; i <= n; i ++)
{
vector res;
while(!S.empty() && S.begin()->first < 0)
{
int t = S.begin()->second;
res.push_back(t);
S.erase(S.begin());
st[t] = true;
}
for(auto x : res)
{
del(x);
}
cout << res.size() << ' ';
}
cout << endl;
}
int main()
{
IOS
int _;
cin >> _;
while(_ --)
{
solve();
}
return 0;
}
构造题,看到的时候觉得应该可以往二进制角度去想
不考虑空序列的话,[0]是有1个上升子序列,[0 1]有三个子序列,增加了2个,这2个是[1]自身的一个和将[0]的所有上升子序列接到[1]前面,总共有两个
[0 1 2]是7个,增加了4个,分别是[2]的1个和[0 1]的3个接到[2]前面新生成的3个
以此类推0 1 2 3 4.....,分别依次增加8个、16个、32个.....
如果在[0 1 2 3 4]后再加一个2的话,依旧是增加了4个,按照先递增再递减的顺序是不会对彼此产生影响的。
这样就符合了二进制的条件。
#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
typedef long long ll;
const int N = 210;
ll a[N];
void solve()
{
ll x;
cin >> x;
x --;
vector ans;
for(int i = 0; ; i ++)
{
if(a[i] <= x && a[i + 1] > x)
{
for(int j = 0; j <= i; j ++)ans.push_back(j);
x -= a[i];
break;
}
}
for(int i = 62; i >= 0; i --)
{
if(x >> i & 1)ans.push_back(i);
}
cout << ans.size() << endl;
for(auto xx : ans)cout << xx << ' ';
cout << endl;
}
int main()
{
IOS
a[0] = 1;
int i = 1;
for(i = 1; i <= 61; i ++)
{
a[i] = a[i - 1] * 2 + 1;
}
int _;
cin >> _;
while(_ --)
{
solve();
}
return 0;
}