LCP Array(思维)

本文探讨了在给定条件下,如何通过分析最大相邻后缀的最长公共前缀数组,来计算符合特定条件的字符串组合数量,并提供了实现该计算的代码示例。

LCP Array

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 90    Accepted Submission(s): 26

Problem Description
Peter has a string s=s1s2...sn, let suffi=sisi+1...sn be the suffix start with i-th character of s. Peter knows the lcp (longest common prefix) of each two adjacent suffixes which denotes as ai=lcp(suffi,suffi+1)(1i<n).
Given the lcp array, Peter wants to know how many strings containing lowercase English letters only will satisfy the lcp array. The answer may be too large, just print it modulo 109+7.
 

 

Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first line contains an integer n (2n105) -- the length of the string. The second line contains n1 integers: a1,a2,...,an1 (0ain).
The sum of values of n in all test cases doesn't exceed 106.
 

 

Output
For each test case output one integer denoting the answer. The answer must be printed modulo 109+7.
 

 

Sample Input
3 3 0 0 4 3 2 1 3 1 2
 

 

Sample Output
16250 26 0

题解:给出最大相邻后缀的最大前缀让找小写字母组成的串的种数

可以找到规律,当出现数组不等于0的时候,必然是递减的;然后找里面0和连续递减串的个数;

就是26*25^m

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
const int INF=0x3f3f3f3f;
#define SI(x) scanf("%d",&x)
#define PI(x) printf("%d",x)
#define P_ printf(" ")
#define mem(x,y) memset(x,y,sizeof(x))
typedef long long LL;
const int MOD=1e9+7;
const int MAXN=1e5+100;
int a[MAXN];
LL solve(int N){
    int cnt=N;
    a[N]=0;
    for(int i=2;i<=N;i++){
        if(a[i-1]!=0&&a[i]!=a[i-1]-1)return 0;
        if(a[i-1])cnt--;
    }
    LL ans=26;
    for(int i=1;i<cnt;i++){
        ans=ans*25%MOD;
    }
    return ans;
}
int main(){
    int T,N;
    SI(T);
    while(T--){
        SI(N);
        int cnt;
        for(int i=1;i<N;i++){
            SI(a[i]);
        }
        printf("%I64d\n",solve(N));
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/handsomecui/p/5246030.html

​ 前言 JavaScript作为现代Web应用的核心技术,其性能直接影响用户体验。随着应用复杂度增加,性能优化成为开发者必须掌握的技能。本文将从多个维度深入探讨JavaScript性能优化的实战策略和技巧。 一、代码层面优化 1.1 减少DOM操作 DOM操作是JavaScript中最耗性能的操作之一,应尽量减少DOM访问和修改次数。 实战技巧: // 不佳实践:频繁操作DOM for (let i = 0; i < 1000; i++) { document.getElementById('list').innerHTML += `<li>Item ${i}</li>`; } // 优化实践:使用文档片段批量操作 const fragment = document.createDocumentFragment(); for (let i = 0; i < 1000; i++) { const li = document.createElement('li'); li.textContent = `Item ${i}`; fragment.appendChild(li); } document.getElementById('list').appendChild(fragment); 1.2 事件委托 利用事件冒泡机制,减少事件处理器的数量。 // 不佳实践:为每个元素绑定事件 document.querySelectorAll('.item').forEach(item => { item.addEventListener('click', handleClick); }); // 优化实践:事件委托 document.getElementById('container').addEventListener('click', (e) => { if (e.target.classList.contains('item')) { handleClick(e); } }); 1.3 避免不必要的计算 缓存重复使用的计算结果和DOM查询。 // 不佳实践:重复计算和查询 function calculateWidth() { const element = document.getElementById('content'); return element.offsetWidth * 0.8; } // 优化实践:缓存结果 let cachedWidth = null; function calculateWidth() { if (cachedWidth === null) { const element = document.getElementById('content'); cachedWidth = element.offsetWidth * 0.8; } return cachedWidth; } 1.4 使用Web Worker处理密集型任务 将CPU密集型任务转移到Web Worker,避免阻塞主线程。 // 主线程代码 const worker = new Worker('task.js'); worker.postMessage({ data: largeData }); worker.onmessage = (e) => { console.log('Result:', e.data); }; // task.js self.onmessage = (e) => { const result = processLargeData(e.data); self.postMessage(result); }; 二、内存管理优化 2.1 避免内存泄漏 常见内存泄漏场景及解决方案: // 1. 意外的全局变量 function leak() { leakedVar = '这是一个全局变量'; // 未使用var/let/const } // 2. 被遗忘的定时器 const intervalId = setInterval(() => { // 操作... }, 1000); // 需要时清除:clearInterval(intervalId); // 3. DOM引用 const elements = { button: document.getElementById('button') }; // 即使从DOM移除,elements.button仍保留引用 2.2 合理使用对象池 对于频繁创建和销毁的对象,使用对象池技术。 class ObjectPool { constructor(createFn) { this.createFn = createFn; this.pool = []; } get() { return this.pool.length > 0 ? this.pool.pop() : this.createFn(); } release(obj) { this.pool.push(obj); } } // 使用示例 const particlePool = new ObjectPool(() => ({ x: 0, y: 0, vx: 0, vy: 0, active: false })); 三、网络性能优化 3.1 代码拆分懒加载 使用动态import实现按需加载。 // 静态导入 // import { heavyModule } from './heavy-module'; // 动态导入(懒加载) button.addEventListener('click', async () => { const { heavyModule } = await import('./heavy-module'); heavyModule.doWork(); }); 3.2 资源预加载 使用<link rel="preload">或Resource Hints。 <!-- 预加载关键资源 --> <link rel="preload" href="critical.js" as="script"> <link rel="preload" href="important.css" as="style"> 四、渲染性能优化 4.1 减少重绘和回流 优化策略: // 不佳实践:多次修改样式引起多次回流 element.style.width = '100px'; element.style.height = '200px'; element.style.margin = '10px'; // 优化实践1:使用cssText批量修改 element.style.cssText = 'width: 100px; height: 200px; margin: 10px;'; // 优化实践2:使用classList element.classList.add('new-style'); // 优化实践3:离线DOM操作 const container = document.getElementById('container'); container.style.display = 'none'; // 批量DOM操作... container.style.display = 'block'; 4.2 使用requestAnimationFrame 优化动画性能,确保浏览器刷新率同步。 function animate() { // 动画逻辑 requestAnimationFrame(animate); } requestAnimationFrame(animate); 4.3 使用WebGL进行复杂图形处理 对于数据可视化、游戏等高性能图形需求,考虑使用WebGL。 五、算法数据结构优化 5.1 选择合适的数据结构 根据场景选择最优数据结构。 // 需要快速查找时使用Set/Map const largeSet = new Set(largeArray); console.log(largeSet.has('target')); // O(1)时间复杂度 // 需要有序数据时使用数组 const sortedArray = [...largeSet].sort(); 5.2 优化循环性能 // 不佳实践:在循环中执行昂贵操作 for (let i = 0; i < array.length; i++) { expensiveOperation(array[i]); } // 优化实践1:缓存长度 for (let i = 0, len = array.length; i < len; i++) { expensiveOperation(array[i]); } // 优化实践2:使用更快的循环方法 array.forEach(item => { expensiveOperation(item); }); 六、工具监控 6.1 性能分析工具 6.2 实时性能监控 // 监控长任务 const observer = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { if (entry.duration > 50) { console.warn('长任务 detected:', entry); } } }); observer.observe({ entryTypes: ['longtask'] }); // 监控FPS let frameCount = 0; let lastTime = performance.now(); function checkFPS() { frameCount++; const currentTime = performance.now(); if (currentTime - lastTime >= 1000) { const fps = Math.round((frameCount * 1000) / (currentTime - lastTime)); if (fps < 30) { console.warn('低FPS:', fps); } frameCount = 0; lastTime = currentTime; } requestAnimationFrame(checkFPS); } checkFPS(); 七、框架特定优化 7.1 React优化实践 // 使用React.memo避免不必要的重渲染 const ExpensiveComponent = React.memo(({ data }) => { // 组件逻辑 }); // 使用useCallback和useMemo缓存值和函数 const memoizedCallback = useCallback(() => { doSomething(a, b); }, [a, b]); const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); 7.2 Vue优化实践 // 使用v-once和v-memo <template> <div v-memo="[value]"> {{ value }} </div> </template> // 合理使用计算属性 computed: { optimizedData() { // 只有依赖变化时才重新计算 return this.heavyComputation(this.sourceData); } } 总结 JavaScript性能优化是一个持续的过程,需要开发者从多个维度综合考虑。关键点包括: 性能优化不是一蹴而就的,应该在开发过程中持续关注,并通过测试确保优化效果。记住,最好的优化往往是那些不需要复杂技巧的简单改进——比如删除不必要的代码或选择更高效的算法。 延伸阅读 通过实践这些优化技巧,您可以显著提升JavaScript应用的性能,为用户提供更流畅的体验。 ​生成思维导图
09-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值