日志统计
思路:
1.如果对id排序,那么对每一个id的都要维护一个时间序列(或者对一个id使用完后清零)
2.如果对ts排序,那么只需要维护一个id数组,和一个st状态数组,相对方便简单
3.末尾时间i,开头时间j是双指针
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define ts first
#define id second
typedef pair<int,int> PII;
const int N = 100010;
int n,d,k;
PII logs[N];
bool st[N];
int cnt[N];
int main(void)
{
cin >> n >> d >> k;
for(int i = 0; i < n; i++)
scanf("%d%d", &logs[i].ts , &logs[i].id);
sort(logs, logs + n);
for(int i = 0, j = 0; i < n; i++)
{
int id = logs[i].id;
cnt[id] ++;
//必须在控制时间范围z之后在判断是否多于k,因为两个时间可能存在跨度,导致超出时间范围
while(logs[i].ts - logs[j].ts >= d)
{
int id1 = logs[j].id;
cnt[id1] --;
j++;
}
if(cnt[id] >= k) st[id] = true;
}
for(int i = 0; i < N; i++)
if(st[i])
printf("%d
",i);
return 0;
}
完全二叉树的权值
思路:
1.完全二叉树每一层的起点i: i*= 2;
2.每一层的个数: 1 << (d-1)
3.i和每一层的遍历j,构成双指针
代码:
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long int LL;
const int N = 100010;
int num[N];
int n, ans;
LL maxv = -1e18;
int main(void)
{
cin >> n;
for(int i = 1; i <= n; i++)
scanf("%d",&num[i]);
//i控制每一层的起点,d控制深度,可以用来求每一层的个数
for(int i = 1 , d = 1; i <= n; i *= 2 ,d++)
{
LL sum = 0;
for(int j = i; j < i + (1 << (d-1)) && j <= n; j++)
sum += num[j];
//第一次将maxv的初值为0,没有考虑到负值的情况
if(sum > maxv)
{
maxv = sum;
ans = d;
}
}
cout << ans << endl;
return 0;
}